1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: EnhancedCustomShape2d.cxx,v $
10 * $Revision: 1.31.146.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include "EnhancedCustomShape2d.hxx"
34 #include "EnhancedCustomShapeGeometry.hxx"
35 #include "EnhancedCustomShapeTypeNames.hxx"
36 #include "EnhancedCustomShapeFunctionParser.hxx"
37 #include <svx/svdoashp.hxx>
38 #include <svx/svdtrans.hxx>
39 #include <svx/svdocirc.hxx>
40 #include <svx/svdogrp.hxx>
41 #include <svx/svdopath.hxx>
43 #include <svx/svdocapt.hxx>
45 #include <svx/svdpage.hxx>
46 #include <svx/xflclit.hxx>
47 #include <svx/sdasaitm.hxx>
48 #include <svx/svdmodel.hxx>
50 #include <rtl/math.hxx>
51 #include <svx/xfillit0.hxx>
52 #include <svx/xlnstit.hxx>
53 #include <svx/xlnedit.hxx>
54 #include <svx/xlnstwit.hxx>
55 #include <svx/xlnedwit.hxx>
56 #include <svx/xlnstcit.hxx>
57 #include <svx/xlnedcit.hxx>
58 #include <svx/xflgrit.hxx>
59 #include <svx/xflhtit.hxx>
60 #include <svx/xbtmpit.hxx>
61 #include <svx/xgrad.hxx>
62 #include <svx/xbitmap.hxx>
63 #include <svx/xhatch.hxx>
64 #include <com/sun/star/awt/Size.hpp>
65 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
66 #ifndef __COM_SUN_STAR_DRAWING_ENHANCEDCUSTOMSHAPESEGMENTCOMMAND_HPP__
67 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
69 #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
70 #include <boost/shared_ptr.hpp>
72 #include <basegfx/numeric/ftools.hxx>
73 #include <basegfx/color/bcolortools.hxx>
74 #include <basegfx/polygon/b2dpolygon.hxx>
77 #include <basegfx/polygon/b2dpolygontools.hxx>
81 using namespace ::com::sun::star::uno
;
82 using namespace ::com::sun::star::drawing
;
83 using namespace ::com::sun::star::drawing::EnhancedCustomShapeSegmentCommand
;
85 void EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( EnhancedCustomShapeParameter
& rParameter
, const sal_Int32 nValue
)
87 sal_uInt32 nDat
= (sal_uInt32
)nValue
;
88 sal_Int32 nNewValue
= nValue
;
90 // check if this is a special point
91 if ( ( nDat
>> 16 ) == 0x8000 )
93 nNewValue
= (sal_uInt16
)nDat
;
94 rParameter
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
97 rParameter
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
98 rParameter
.Value
<<= nNewValue
;
101 rtl::OUString
EnhancedCustomShape2d::GetEquation( const sal_uInt16 nFlags
, sal_Int16 nP1
, sal_Int16 nP2
, sal_Int16 nP3
)
103 rtl::OUString aEquation
;
104 sal_Bool b1Special
= ( nFlags
& 0x2000 ) != 0;
105 sal_Bool b2Special
= ( nFlags
& 0x4000 ) != 0;
106 sal_Bool b3Special
= ( nFlags
& 0x8000 ) != 0;
107 switch( nFlags
& 0xff )
112 sal_Int32 nOptimize
= 0;
128 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
133 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
137 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
138 aEquation
+= rtl::OUString( (sal_Unicode
)'+' );
139 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
143 if ( b3Special
|| nP3
)
145 aEquation
+= rtl::OUString( (sal_Unicode
)'-' );
146 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
152 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
153 if ( b2Special
|| ( nP2
!= 1 ) )
155 aEquation
+= rtl::OUString( (sal_Unicode
)'*' );
156 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
158 if ( b3Special
|| ( ( nP3
!= 1 ) && ( nP3
!= 0 ) ) )
160 aEquation
+= rtl::OUString( (sal_Unicode
)'/' );
161 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
167 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "(" ) );
168 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
169 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) );
170 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
171 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")/2" ) );
176 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "abs(" ) );
177 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
178 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
183 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "min(" ) );
184 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
185 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
186 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
187 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
192 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "max(" ) );
193 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
194 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
195 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
196 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
201 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "if(" ) );
202 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
203 aEquation
+= rtl::OUString( (sal_Unicode
)',' );
204 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
205 aEquation
+= rtl::OUString( (sal_Unicode
)',' );
206 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
207 aEquation
+= rtl::OUString( (sal_Unicode
)')' );
212 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) );
213 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
214 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
215 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
216 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) );
217 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
218 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
219 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
220 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) );
221 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
222 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
223 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
224 aEquation
+= rtl::OUString( (sal_Unicode
)')' );
229 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "atan2(" ) );
230 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
231 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
232 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
233 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")/(pi/180)" ) );
238 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
239 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*sin(" ) );
240 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
241 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))" ) );
246 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
247 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*cos(" ) );
248 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
249 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))" ) );
254 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
255 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
256 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "cos(atan2(" ) );
257 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
258 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
259 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
260 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) );
265 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
266 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
267 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sin(atan2(" ) );
268 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
269 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) );
270 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
271 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) );
276 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) );
277 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
278 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
283 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
284 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*sqrt(1-(" ) );
285 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
286 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
287 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
288 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
289 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(" ) );
290 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
291 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) );
292 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
293 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) );
298 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
299 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*tan(" ) );
300 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
301 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) );
306 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) );
307 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
308 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
309 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
310 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-" ) );
311 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
312 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) );
313 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
314 aEquation
+= rtl::OUString( (sal_Unicode
)')' );
319 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "(cos(" ) );
320 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
321 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
322 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
323 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800)+sin(" ) );
324 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
325 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
326 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
327 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800))+10800" ) );
332 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-(sin(" ) );
333 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
334 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
335 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP1
, b1Special
);
336 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800)-cos(" ) );
337 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP3
, b3Special
);
338 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) );
339 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation
, nP2
, b2Special
);
340 aEquation
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800))+10800" ) );
347 void EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( rtl::OUString
& rParameter
, const sal_Int16 nPara
, const sal_Bool bIsSpecialValue
)
349 if ( bIsSpecialValue
)
353 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "?" ) );
354 rParameter
+= rtl::OUString::valueOf( (sal_Int32
)( nPara
& 0xff ) );
355 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
361 case DFF_Prop_adjustValue
:
362 case DFF_Prop_adjust2Value
:
363 case DFF_Prop_adjust3Value
:
364 case DFF_Prop_adjust4Value
:
365 case DFF_Prop_adjust5Value
:
366 case DFF_Prop_adjust6Value
:
367 case DFF_Prop_adjust7Value
:
368 case DFF_Prop_adjust8Value
:
369 case DFF_Prop_adjust9Value
:
370 case DFF_Prop_adjust10Value
:
372 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "$" ) );
373 rParameter
+= rtl::OUString::valueOf( (sal_Int32
)( nPara
- DFF_Prop_adjustValue
) );
374 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
377 case DFF_Prop_geoLeft
:
379 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "left" ) );
382 case DFF_Prop_geoTop
:
384 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "top" ) );
387 case DFF_Prop_geoRight
:
389 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "right" ) );
392 case DFF_Prop_geoBottom
:
394 rParameter
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "bottom" ) );
402 rParameter
+= rtl::OUString::valueOf( (sal_Int32
)( nPara
) );
406 void EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( EnhancedCustomShapeParameter
& rParameter
, const sal_Int32 nPara
, const sal_Bool bIsSpecialValue
, sal_Bool bHorz
)
408 sal_Int32 nValue
= 0;
409 if ( bIsSpecialValue
)
411 if ( ( nPara
>= 0x100 ) && ( nPara
<= 0x107 ) )
413 nValue
= nPara
& 0xff;
414 rParameter
.Type
= EnhancedCustomShapeParameterType::ADJUSTMENT
;
416 else if ( ( nPara
>= 3 ) && ( nPara
<= 0x82 ) )
419 rParameter
.Type
= EnhancedCustomShapeParameterType::EQUATION
;
421 else if ( nPara
== 0 )
425 rParameter
.Type
= EnhancedCustomShapeParameterType::LEFT
;
427 rParameter
.Type
= EnhancedCustomShapeParameterType::TOP
;
429 else if ( nPara
== 1 )
433 rParameter
.Type
= EnhancedCustomShapeParameterType::RIGHT
;
435 rParameter
.Type
= EnhancedCustomShapeParameterType::BOTTOM
;
437 else if ( nPara
== 2 ) // means to be centered, but should not be
438 { // used in our implementation
440 rParameter
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
445 rParameter
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
451 rParameter
.Type
= EnhancedCustomShapeParameterType::NORMAL
;
453 rParameter
.Value
<<= nValue
;
456 sal_Bool
EnhancedCustomShape2d::ConvertSequenceToEnhancedCustomShape2dHandle(
457 const com::sun::star::beans::PropertyValues
& rHandleProperties
,
458 EnhancedCustomShape2d::Handle
& rDestinationHandle
)
460 sal_Bool bRetValue
= sal_False
;
461 sal_uInt32 i
, nProperties
= rHandleProperties
.getLength();
464 rDestinationHandle
.nFlags
= 0;
465 for ( i
= 0; i
< nProperties
; i
++ )
467 const com::sun::star::beans::PropertyValue
& rPropVal
= rHandleProperties
[ i
];
469 const rtl::OUString
sPosition ( RTL_CONSTASCII_USTRINGPARAM( "Position" ) );
470 const rtl::OUString
sMirroredX ( RTL_CONSTASCII_USTRINGPARAM( "MirroredX" ) );
471 const rtl::OUString
sMirroredY ( RTL_CONSTASCII_USTRINGPARAM( "MirroredY" ) );
472 const rtl::OUString
sSwitched ( RTL_CONSTASCII_USTRINGPARAM( "Switched" ) );
473 const rtl::OUString
sPolar ( RTL_CONSTASCII_USTRINGPARAM( "Polar" ) );
474 // const rtl::OUString sMap ( RTL_CONSTASCII_USTRINGPARAM( "Map" ) );
475 const rtl::OUString
sRadiusRangeMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMinimum" ) );
476 const rtl::OUString
sRadiusRangeMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMaximum" ) );
477 const rtl::OUString
sRangeXMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMinimum" ) );
478 const rtl::OUString
sRangeXMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMaximum" ) );
479 const rtl::OUString
sRangeYMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMinimum" ) );
480 const rtl::OUString
sRangeYMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMaximum" ) );
482 if ( rPropVal
.Name
.equals( sPosition
) )
484 if ( rPropVal
.Value
>>= rDestinationHandle
.aPosition
)
485 bRetValue
= sal_True
;
487 else if ( rPropVal
.Name
.equals( sMirroredX
) )
489 sal_Bool bMirroredX
= sal_Bool();
490 if ( rPropVal
.Value
>>= bMirroredX
)
493 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_MIRRORED_X
;
496 else if ( rPropVal
.Name
.equals( sMirroredY
) )
498 sal_Bool bMirroredY
= sal_Bool();
499 if ( rPropVal
.Value
>>= bMirroredY
)
502 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_MIRRORED_Y
;
505 else if ( rPropVal
.Name
.equals( sSwitched
) )
507 sal_Bool bSwitched
= sal_Bool();
508 if ( rPropVal
.Value
>>= bSwitched
)
511 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_SWITCHED
;
514 else if ( rPropVal
.Name
.equals( sPolar
) )
516 if ( rPropVal
.Value
>>= rDestinationHandle
.aPolar
)
517 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_POLAR
;
519 /* seems not to be used.
520 else if ( rPropVal.Name.equals( sMap ) )
522 com::sun::star::drawing::EnhancedCustomShapeParameterPair aMap;
523 if ( rPropVal.Value >>= aMap )
525 if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aMap.First ) )
526 rDestinationHandle.Flags |= 0x800;
527 if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aMap.Second ) )
528 rDestinationHandle.Flags |= 0x1000;
529 rDestinationHandle.Flags |= 0x10;
533 else if ( rPropVal
.Name
.equals( sRadiusRangeMinimum
) )
535 if ( rPropVal
.Value
>>= rDestinationHandle
.aRadiusRangeMinimum
)
536 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_RADIUS_RANGE_MINIMUM
;
538 else if ( rPropVal
.Name
.equals( sRadiusRangeMaximum
) )
540 if ( rPropVal
.Value
>>= rDestinationHandle
.aRadiusRangeMaximum
)
541 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM
;
543 else if ( rPropVal
.Name
.equals( sRangeXMinimum
) )
545 if ( rPropVal
.Value
>>= rDestinationHandle
.aXRangeMinimum
)
546 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_RANGE_X_MINIMUM
;
548 else if ( rPropVal
.Name
.equals( sRangeXMaximum
) )
550 if ( rPropVal
.Value
>>= rDestinationHandle
.aXRangeMaximum
)
551 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_RANGE_X_MAXIMUM
;
553 else if ( rPropVal
.Name
.equals( sRangeYMinimum
) )
555 if ( rPropVal
.Value
>>= rDestinationHandle
.aYRangeMinimum
)
556 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_RANGE_Y_MINIMUM
;
558 else if ( rPropVal
.Name
.equals( sRangeYMaximum
) )
560 if ( rPropVal
.Value
>>= rDestinationHandle
.aYRangeMaximum
)
561 rDestinationHandle
.nFlags
|= HANDLE_FLAGS_RANGE_Y_MAXIMUM
;
568 const sal_Int32
* EnhancedCustomShape2d::ApplyShapeAttributes( const SdrCustomShapeGeometryItem
& rGeometryItem
)
570 const sal_Int32
* pDefData
= NULL
;
571 const mso_CustomShape
* pDefCustomShape
= GetCustomShapeContent( eSpType
);
572 if ( pDefCustomShape
)
573 pDefData
= pDefCustomShape
->pDefData
;
575 //////////////////////
576 // AdjustmentValues //
577 //////////////////////
578 const rtl::OUString
sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
579 const Any
* pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sAdjustmentValues
);
581 *pAny
>>= seqAdjustmentValues
;
586 const rtl::OUString
sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
587 const Any
* pViewBox
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sViewBox
);
588 com::sun::star::awt::Rectangle aViewBox
;
589 if ( pViewBox
&& (*pViewBox
>>= aViewBox
) )
591 nCoordLeft
= aViewBox
.X
;
592 nCoordTop
= aViewBox
.Y
;
593 nCoordWidth
= labs( aViewBox
.Width
);
594 nCoordHeight
= labs( aViewBox
.Height
);
596 const rtl::OUString
sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
598 //////////////////////
599 // Path/Coordinates //
600 //////////////////////
601 const rtl::OUString
sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
602 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sPath
, sCoordinates
);
604 *pAny
>>= seqCoordinates
;
606 /////////////////////
607 // Path/GluePoints //
608 /////////////////////
609 const rtl::OUString
sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
610 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sPath
, sGluePoints
);
612 *pAny
>>= seqGluePoints
;
617 const rtl::OUString
sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
618 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sPath
, sSegments
);
620 *pAny
>>= seqSegments
;
625 const rtl::OUString
sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
626 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sPath
, sStretchX
);
629 sal_Int32 nStretchX
= 0;
630 if ( *pAny
>>= nStretchX
)
637 const rtl::OUString
sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
638 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sPath
, sStretchY
);
641 sal_Int32 nStretchY
= 0;
642 if ( *pAny
>>= nStretchY
)
646 /////////////////////
647 // Path/TextFrames //
648 /////////////////////
649 const rtl::OUString
sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
650 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sPath
, sTextFrames
);
652 *pAny
>>= seqTextFrames
;
657 const rtl::OUString
sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
658 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sEquations
);
660 *pAny
>>= seqEquations
;
665 const rtl::OUString
sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
666 pAny
= ((SdrCustomShapeGeometryItem
&)rGeometryItem
).GetPropertyValueByName( sHandles
);
668 *pAny
>>= seqHandles
;
673 EnhancedCustomShape2d::~EnhancedCustomShape2d()
677 EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject
* pAObj
) :
678 SfxItemSet ( pAObj
->GetMergedItemSet() ),
679 pCustomShapeObj ( pAObj
),
680 eSpType ( mso_sptNil
),
683 nCoordWidth ( 21600 ),
684 nCoordHeight ( 21600 ),
685 nXRef ( 0x80000000 ),
686 nYRef ( 0x80000000 ),
689 bTextFlow ( sal_False
),
690 bFilled ( ((const XFillStyleItem
&)pAObj
->GetMergedItem( XATTR_FILLSTYLE
)).GetValue() != XFILL_NONE
),
691 bStroked ( ((const XLineStyleItem
&)pAObj
->GetMergedItem( XATTR_LINESTYLE
)).GetValue() != XLINE_NONE
),
692 bFlipH ( sal_False
),
695 // bTextFlow needs to be set before clearing the TextDirection Item
697 ClearItem( SDRATTR_TEXTDIRECTION
); //SJ: vertical writing is not required, by removing this item no outliner is created
699 // For primitive rendering, shadow handling is done completely based on the geometry, so i removed it here
700 ClearItem(SDRATTR_SHADOW
);
702 Point
aP( pCustomShapeObj
->GetSnapRect().Center() );
703 Size
aS( pCustomShapeObj
->GetLogicRect().GetSize() );
704 aP
.X() -= aS
.Width() / 2;
705 aP
.Y() -= aS
.Height() / 2;
706 aLogicRect
= Rectangle( aP
, aS
);
708 const rtl::OUString
sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
709 const rtl::OUString
sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
710 const rtl::OUString
sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
712 rtl::OUString sShapeType
;
713 SdrCustomShapeGeometryItem
& rGeometryItem
= (SdrCustomShapeGeometryItem
&)(const SdrCustomShapeGeometryItem
&)pCustomShapeObj
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
);
714 Any
* pAny
= rGeometryItem
.GetPropertyValueByName( sType
);
716 *pAny
>>= sShapeType
;
717 eSpType
= EnhancedCustomShapeTypeNames::Get( sShapeType
);
719 pAny
= rGeometryItem
.GetPropertyValueByName( sMirroredX
);
722 pAny
= rGeometryItem
.GetPropertyValueByName( sMirroredY
);
726 if ( pCustomShapeObj
->ISA( SdrObjCustomShape
) ) // should always be a SdrObjCustomShape, but you don't know
727 nRotateAngle
= (sal_Int32
)(((SdrObjCustomShape
*)pCustomShapeObj
)->GetObjectRotation() * 100.0);
729 nRotateAngle
= pCustomShapeObj
->GetRotateAngle();
731 /*const sal_Int32* pDefData =*/ ApplyShapeAttributes( rGeometryItem
);
734 case mso_sptCan
: nColorData
= 0x20400000; break;
735 case mso_sptCube
: nColorData
= 0x302e0000; break;
736 case mso_sptActionButtonBlank
: nColorData
= 0x502ce400; break;
737 case mso_sptActionButtonHome
: nColorData
= 0x702ce4ce; break;
738 case mso_sptActionButtonHelp
: nColorData
= 0x602ce4c0; break;
739 case mso_sptActionButtonInformation
: nColorData
= 0x702ce4c5; break;
740 case mso_sptActionButtonBackPrevious
: nColorData
= 0x602ce4c0; break;
741 case mso_sptActionButtonForwardNext
: nColorData
= 0x602ce4c0; break;
742 case mso_sptActionButtonBeginning
: nColorData
= 0x602ce4c0; break;
743 case mso_sptActionButtonEnd
: nColorData
= 0x602ce4c0; break;
744 case mso_sptActionButtonReturn
: nColorData
= 0x602ce4c0; break;
745 case mso_sptActionButtonDocument
: nColorData
= 0x702ce4ec; break;
746 case mso_sptActionButtonSound
: nColorData
= 0x602ce4c0; break;
747 case mso_sptActionButtonMovie
: nColorData
= 0x602ce4c0; break;
748 case mso_sptBevel
: nColorData
= 0x502ce400; break;
749 case mso_sptFoldedCorner
: nColorData
= 0x20e00000; break;
750 case mso_sptSmileyFace
: nColorData
= 0x20e00000; break;
753 if( sShapeType
.getLength() > 4 &&
754 sShapeType
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "col-" )))
756 nColorData
= sShapeType
.copy( 4 ).toInt32( 16 );
760 case mso_sptCurvedLeftArrow
:
761 case mso_sptCurvedRightArrow
:
762 case mso_sptCurvedUpArrow
:
763 case mso_sptCurvedDownArrow
: nColorData
= 0x2d000000; break;
764 case mso_sptRibbon2
: nColorData
= 0x30ee0000; break;
765 case mso_sptRibbon
: nColorData
= 0x30ee0000; break;
767 case mso_sptEllipseRibbon2
: nColorData
= 0x30ee0000; break;
768 case mso_sptEllipseRibbon
: nColorData
= 0x30ee0000; break;
770 case mso_sptVerticalScroll
: nColorData
= 0x30ee0000; break;
771 case mso_sptHorizontalScroll
: nColorData
= 0x30ee0000; break;
775 fXScale
= nCoordWidth
== 0 ? 0.0 : (double)aLogicRect
.GetWidth() / (double)nCoordWidth
;
776 fYScale
= nCoordHeight
== 0 ? 0.0 : (double)aLogicRect
.GetHeight() / (double)nCoordHeight
;
777 if ( (sal_uInt32
)nXRef
!= 0x80000000 && aLogicRect
.GetHeight() )
779 fXRatio
= (double)aLogicRect
.GetWidth() / (double)aLogicRect
.GetHeight();
787 if ( (sal_uInt32
)nYRef
!= 0x80000000 && aLogicRect
.GetWidth() )
789 fYRatio
= (double)aLogicRect
.GetHeight() / (double)aLogicRect
.GetWidth();
798 sal_Int32 i
, nLength
= seqEquations
.getLength();
803 vNodesSharedPtr
.resize( nLength
);
804 for ( i
= 0; i
< seqEquations
.getLength(); i
++ )
808 vNodesSharedPtr
[ i
] = EnhancedCustomShape::FunctionParser::parseFunction( seqEquations
[ i
], *this );
810 catch ( EnhancedCustomShape::ParseError
& )
816 double EnhancedCustomShape2d::GetEnumFunc( const EnumFunc eFunc
) const
821 case ENUM_FUNC_PI
: fRet
= F_PI
; break;
822 case ENUM_FUNC_LEFT
: fRet
= 0.0; break;
823 case ENUM_FUNC_TOP
: fRet
= 0.0; break;
824 case ENUM_FUNC_RIGHT
: fRet
= (double)nCoordWidth
* fXRatio
; break;
825 case ENUM_FUNC_BOTTOM
: fRet
= (double)nCoordHeight
* fYRatio
; break;
826 case ENUM_FUNC_XSTRETCH
: fRet
= nXRef
; break;
827 case ENUM_FUNC_YSTRETCH
: fRet
= nYRef
; break;
828 case ENUM_FUNC_HASSTROKE
: fRet
= bStroked
? 1.0 : 0.0; break;
829 case ENUM_FUNC_HASFILL
: fRet
= bFilled
? 1.0 : 0.0; break;
830 case ENUM_FUNC_WIDTH
: fRet
= nCoordWidth
; break;
831 case ENUM_FUNC_HEIGHT
: fRet
= nCoordHeight
; break;
832 case ENUM_FUNC_LOGWIDTH
: fRet
= aLogicRect
.GetWidth(); break;
833 case ENUM_FUNC_LOGHEIGHT
: fRet
= aLogicRect
.GetHeight(); break;
837 double EnhancedCustomShape2d::GetAdjustValueAsDouble( const sal_Int32 nIndex
) const
839 double fNumber
= 0.0;
840 if ( nIndex
< seqAdjustmentValues
.getLength() )
842 if ( seqAdjustmentValues
[ nIndex
].Value
.getValueTypeClass() == TypeClass_DOUBLE
)
843 seqAdjustmentValues
[ nIndex
].Value
>>= fNumber
;
846 sal_Int32 nNumber
= 0;
847 seqAdjustmentValues
[ nIndex
].Value
>>= nNumber
;
848 fNumber
= (double)nNumber
;
853 double EnhancedCustomShape2d::GetEquationValueAsDouble( const sal_Int32 nIndex
) const
855 double fNumber
= 0.0;
856 if ( nIndex
< (sal_Int32
)vNodesSharedPtr
.size() )
858 if ( vNodesSharedPtr
[ nIndex
].get() )
861 fNumber
= (*vNodesSharedPtr
[ nIndex
])();
862 if ( !rtl::math::isFinite( fNumber
) )
867 /* sal_Bool bUps = sal_True; */
872 sal_Int32
EnhancedCustomShape2d::GetAdjustValueAsInteger( const sal_Int32 nIndex
, const sal_Int32 nDefault
) const
874 sal_Int32 nNumber
= nDefault
;
875 if ( nIndex
< seqAdjustmentValues
.getLength() )
877 if ( seqAdjustmentValues
[ nIndex
].Value
.getValueTypeClass() == TypeClass_DOUBLE
)
880 seqAdjustmentValues
[ nIndex
].Value
>>= fNumber
;
881 nNumber
= (sal_Int32
)fNumber
;
884 seqAdjustmentValues
[ nIndex
].Value
>>= nNumber
;
888 sal_Bool
EnhancedCustomShape2d::SetAdjustValueAsDouble( const double& rValue
, const sal_Int32 nIndex
)
890 sal_Bool bRetValue
= sal_False
;
891 if ( nIndex
< seqAdjustmentValues
.getLength() )
893 // updating our local adjustment sequence
894 seqAdjustmentValues
[ nIndex
].Value
<<= rValue
;
895 seqAdjustmentValues
[ nIndex
].State
= com::sun::star::beans::PropertyState_DIRECT_VALUE
;
896 bRetValue
= sal_True
;
901 Point
EnhancedCustomShape2d::GetPoint( const com::sun::star::drawing::EnhancedCustomShapeParameterPair
& rPair
,
902 const sal_Bool bScale
, const sal_Bool bReplaceGeoSize
) const
905 sal_Bool bExchange
= ( nFlags
& DFF_CUSTOMSHAPE_EXCH
) != 0; // x <-> y
906 sal_uInt32 nPass
= 0;
909 sal_uInt32 nIndex
= nPass
;
915 const EnhancedCustomShapeParameter
& rParameter
= nIndex
? rPair
.Second
: rPair
.First
;
916 if ( nPass
) // height
918 GetParameter( fVal
, rParameter
, sal_False
, bReplaceGeoSize
);
924 if ( nFlags
& DFF_CUSTOMSHAPE_FLIP_V
)
925 fVal
= aLogicRect
.GetHeight() - fVal
;
927 aRetValue
.Y() = (sal_Int32
)fVal
;
931 GetParameter( fVal
, rParameter
, bReplaceGeoSize
, sal_False
);
937 if ( nFlags
& DFF_CUSTOMSHAPE_FLIP_H
)
938 fVal
= aLogicRect
.GetWidth() - fVal
;
940 aRetValue
.X() = (sal_Int32
)fVal
;
943 while ( ++nPass
< 2 );
947 sal_Bool
EnhancedCustomShape2d::GetParameter( double& rRetValue
, const EnhancedCustomShapeParameter
& rParameter
,
948 const sal_Bool bReplaceGeoWidth
, const sal_Bool bReplaceGeoHeight
) const
951 sal_Bool bRetValue
= sal_False
;
952 switch ( rParameter
.Type
)
954 case EnhancedCustomShapeParameterType::ADJUSTMENT
:
956 sal_Int32 nAdjustmentIndex
= 0;
957 if ( rParameter
.Value
>>= nAdjustmentIndex
)
959 rRetValue
= GetAdjustValueAsDouble( nAdjustmentIndex
);
960 bRetValue
= sal_True
;
964 case EnhancedCustomShapeParameterType::EQUATION
:
966 sal_Int32 nEquationIndex
= 0;
967 if ( rParameter
.Value
>>= nEquationIndex
)
969 rRetValue
= GetEquationValueAsDouble( nEquationIndex
);
970 bRetValue
= sal_True
;
974 case EnhancedCustomShapeParameterType::NORMAL
:
976 if ( rParameter
.Value
.getValueTypeClass() == TypeClass_DOUBLE
)
979 if ( rParameter
.Value
>>= fValue
)
982 bRetValue
= sal_True
;
987 sal_Int32 nValue
= 0;
988 if ( rParameter
.Value
>>= nValue
)
991 bRetValue
= sal_True
;
992 if ( bReplaceGeoWidth
&& ( nValue
== nCoordWidth
) )
993 rRetValue
*= fXRatio
;
994 else if ( bReplaceGeoHeight
&& ( nValue
== nCoordHeight
) )
995 rRetValue
*= fYRatio
;
1000 case EnhancedCustomShapeParameterType::LEFT
:
1003 bRetValue
= sal_True
;
1006 case EnhancedCustomShapeParameterType::TOP
:
1009 bRetValue
= sal_True
;
1012 case EnhancedCustomShapeParameterType::RIGHT
:
1014 rRetValue
= nCoordWidth
;
1015 bRetValue
= sal_True
;
1018 case EnhancedCustomShapeParameterType::BOTTOM
:
1020 rRetValue
= nCoordHeight
;
1021 bRetValue
= sal_True
;
1028 // nLumDat 28-31 = number of luminance entries in nLumDat
1029 // nLumDat 27-24 = nLumDatEntry 0
1030 // nLumDat 23-20 = nLumDatEntry 1 ...
1031 // each 4bit entry is to be interpreted as a 10 percent signed luminance changing
1032 sal_Int32
EnhancedCustomShape2d::GetLuminanceChange( sal_uInt32 nIndex
) const
1034 const sal_uInt32 nCount
= nColorData
>> 28;
1038 if ( nIndex
>= nCount
)
1039 nIndex
= nCount
- 1;
1041 const sal_Int32 nLumDat
= nColorData
<< ( ( 1 + nIndex
) << 2 );
1042 return ( nLumDat
>> 28 ) * 10;
1045 Color
EnhancedCustomShape2d::GetColorData( const Color
& rFillColor
, sal_uInt32 nIndex
) const
1047 const sal_Int32 nLuminance
= GetLuminanceChange(nIndex
);
1051 basegfx::BColor aHSVColor
=
1052 basegfx::tools::rgb2hsv(
1053 basegfx::BColor(rFillColor
.GetRed()/255.0,
1054 rFillColor
.GetGreen()/255.0,
1055 rFillColor
.GetBlue()/255.0));
1056 if( nLuminance
> 0 )
1059 aHSVColor
.getGreen() * (1.0-nLuminance
/100.0));
1062 (1.0-nLuminance
/100.0)*aHSVColor
.getBlue());
1064 else if( nLuminance
< 0 )
1067 (1.0+nLuminance
/100.0)*aHSVColor
.getBlue());
1070 aHSVColor
= basegfx::tools::hsv2rgb(aHSVColor
);
1071 return Color( (sal_uInt8
)static_cast< sal_Int32
>( basegfx::clamp(aHSVColor
.getRed(),0.0,1.0) * 255.0 + 0.5 ),
1072 (sal_uInt8
)static_cast< sal_Int32
>( basegfx::clamp(aHSVColor
.getGreen(),0.0,1.0) * 255.0 + 0.5 ),
1073 (sal_uInt8
)static_cast< sal_Int32
>( basegfx::clamp(aHSVColor
.getBlue(),0.0,1.0) * 255.0 + 0.5 ) );
1076 Rectangle
EnhancedCustomShape2d::GetTextRect() const
1078 sal_Int32 nIndex
, nSize
= seqTextFrames
.getLength();
1082 if ( bTextFlow
&& ( nSize
> 1 ) )
1084 Point
aTopLeft( GetPoint( seqTextFrames
[ nIndex
].TopLeft
, sal_True
, sal_True
) );
1085 Point
aBottomRight( GetPoint( seqTextFrames
[ nIndex
].BottomRight
, sal_True
, sal_True
) );
1088 aTopLeft
.X() = aLogicRect
.GetWidth() - aTopLeft
.X();
1089 aBottomRight
.X() = aLogicRect
.GetWidth() - aBottomRight
.X();
1093 aTopLeft
.Y() = aLogicRect
.GetHeight() - aTopLeft
.Y();
1094 aBottomRight
.Y() = aLogicRect
.GetHeight() - aBottomRight
.Y();
1096 Rectangle
aRect( aTopLeft
, aBottomRight
);
1097 aRect
.Move( aLogicRect
.Left(), aLogicRect
.Top() );
1102 sal_uInt32
EnhancedCustomShape2d::GetHdlCount() const
1104 return seqHandles
.getLength();
1107 sal_Bool
EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex
, Point
& rReturnPosition
) const
1109 sal_Bool bRetValue
= sal_False
;
1110 if ( nIndex
< GetHdlCount() )
1113 if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles
[ nIndex
], aHandle
) )
1115 if ( aHandle
.nFlags
& HANDLE_FLAGS_POLAR
)
1117 Point
aReferencePoint( GetPoint( aHandle
.aPolar
, sal_True
, sal_False
) );
1121 GetParameter( fRadius
, aHandle
.aPosition
.First
, sal_False
, sal_False
);
1122 GetParameter( fAngle
, aHandle
.aPosition
.Second
, sal_False
, sal_False
);
1124 double a
= ( 360.0 - fAngle
) * F_PI180
;
1125 double dx
= fRadius
* fXScale
;
1126 double fX
= dx
* cos( a
);
1127 double fY
=-dx
* sin( a
);
1130 Round( fX
+ aReferencePoint
.X() ),
1131 basegfx::fTools::equalZero(fXScale
) ? aReferencePoint
.Y() :
1132 Round( ( fY
* fYScale
) / fXScale
+ aReferencePoint
.Y() ) );
1136 if ( aHandle
.nFlags
& HANDLE_FLAGS_SWITCHED
)
1138 if ( aLogicRect
.GetHeight() > aLogicRect
.GetWidth() )
1140 com::sun::star::drawing::EnhancedCustomShapeParameter aFirst
= aHandle
.aPosition
.First
;
1141 com::sun::star::drawing::EnhancedCustomShapeParameter aSecond
= aHandle
.aPosition
.Second
;
1142 aHandle
.aPosition
.First
= aSecond
;
1143 aHandle
.aPosition
.Second
= aFirst
;
1146 rReturnPosition
= GetPoint( aHandle
.aPosition
, sal_True
, sal_False
);
1148 const GeoStat
aGeoStat( ((SdrObjCustomShape
*)pCustomShapeObj
)->GetGeoStat() );
1149 if ( aGeoStat
.nShearWink
)
1151 double nTan
= aGeoStat
.nTan
;
1152 if ((bFlipV
&&!bFlipH
)||(bFlipH
&&!bFlipV
))
1154 ShearPoint( rReturnPosition
, Point( aLogicRect
.GetWidth() / 2, aLogicRect
.GetHeight() / 2 ), nTan
);
1158 double a
= nRotateAngle
* F_PI18000
;
1159 RotatePoint( rReturnPosition
, Point( aLogicRect
.GetWidth() / 2, aLogicRect
.GetHeight() / 2 ), sin( a
), cos( a
) );
1162 rReturnPosition
.X() = aLogicRect
.GetWidth() - rReturnPosition
.X();
1164 rReturnPosition
.Y() = aLogicRect
.GetHeight() - rReturnPosition
.Y();
1165 rReturnPosition
.Move( aLogicRect
.Left(), aLogicRect
.Top() );
1166 bRetValue
= sal_True
;
1172 sal_Bool
EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nIndex
, const com::sun::star::awt::Point
& rPosition
)
1174 sal_Bool bRetValue
= sal_False
;
1175 if ( nIndex
< GetHdlCount() )
1178 if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles
[ nIndex
], aHandle
) )
1180 sal_Bool bAdjFirst
= aHandle
.aPosition
.First
.Type
== EnhancedCustomShapeParameterType::ADJUSTMENT
;
1181 sal_Bool bAdjSecond
= aHandle
.aPosition
.Second
.Type
== EnhancedCustomShapeParameterType::ADJUSTMENT
;
1182 if ( bAdjFirst
|| bAdjSecond
)
1184 Point
aP( rPosition
.X
, rPosition
.Y
);
1185 // apply the negative object rotation to the controller position
1187 aP
.Move( -aLogicRect
.Left(), -aLogicRect
.Top() );
1189 aP
.X() = aLogicRect
.GetWidth() - aP
.X();
1191 aP
.Y() = aLogicRect
.GetHeight() - aP
.Y();
1194 double a
= -nRotateAngle
* F_PI18000
;
1195 RotatePoint( aP
, Point( aLogicRect
.GetWidth() / 2, aLogicRect
.GetHeight() / 2 ), sin( a
), cos( a
) );
1197 const GeoStat
aGeoStat( ((SdrObjCustomShape
*)pCustomShapeObj
)->GetGeoStat() );
1198 if ( aGeoStat
.nShearWink
)
1200 double nTan
= -aGeoStat
.nTan
;
1201 if ((bFlipV
&&!bFlipH
)||(bFlipH
&&!bFlipV
))
1203 ShearPoint( aP
, Point( aLogicRect
.GetWidth() / 2, aLogicRect
.GetHeight() / 2 ), nTan
);
1206 double fPos1
= aP
.X(); //( bFlipH ) ? aLogicRect.GetWidth() - aP.X() : aP.X();
1207 double fPos2
= aP
.Y(); //( bFlipV ) ? aLogicRect.GetHeight() -aP.Y() : aP.Y();
1211 if ( aHandle
.nFlags
& HANDLE_FLAGS_SWITCHED
)
1213 if ( aLogicRect
.GetHeight() > aLogicRect
.GetWidth() )
1222 sal_Int32 nFirstAdjustmentValue
= 0, nSecondAdjustmentValue
= 0;
1223 aHandle
.aPosition
.First
.Value
>>= nFirstAdjustmentValue
;
1224 aHandle
.aPosition
.Second
.Value
>>= nSecondAdjustmentValue
;
1226 if ( aHandle
.nFlags
& HANDLE_FLAGS_POLAR
)
1228 double fXRef
, fYRef
, fAngle
;
1229 GetParameter( fXRef
, aHandle
.aPolar
.First
, sal_False
, sal_False
);
1230 GetParameter( fYRef
, aHandle
.aPolar
.Second
, sal_False
, sal_False
);
1231 const double fDX
= fPos1
- fXRef
;
1232 fAngle
= -( atan2( -fPos2
+ fYRef
, ( ( fDX
== 0.0L ) ? 0.000000001 : fDX
) ) / F_PI180
);
1233 double fX
= ( fPos1
- fXRef
);
1234 double fY
= ( fPos2
- fYRef
);
1235 double fRadius
= sqrt( fX
* fX
+ fY
* fY
);
1236 if ( aHandle
.nFlags
& HANDLE_FLAGS_RADIUS_RANGE_MINIMUM
)
1239 GetParameter( fMin
, aHandle
.aRadiusRangeMinimum
, sal_False
, sal_False
);
1240 if ( fRadius
< fMin
)
1243 if ( aHandle
.nFlags
& HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM
)
1246 GetParameter( fMax
, aHandle
.aRadiusRangeMaximum
, sal_False
, sal_False
);
1247 if ( fRadius
> fMax
)
1251 SetAdjustValueAsDouble( fRadius
, nFirstAdjustmentValue
);
1253 SetAdjustValueAsDouble( fAngle
, nSecondAdjustmentValue
);
1259 if ( aHandle
.nFlags
& HANDLE_FLAGS_RANGE_X_MINIMUM
) // check if horizontal handle needs to be within a range
1262 GetParameter( fXMin
, aHandle
.aXRangeMinimum
, sal_False
, sal_False
);
1263 if ( fPos1
< fXMin
)
1266 if ( aHandle
.nFlags
& HANDLE_FLAGS_RANGE_X_MAXIMUM
) // check if horizontal handle needs to be within a range
1269 GetParameter( fXMax
, aHandle
.aXRangeMaximum
, sal_False
, sal_False
);
1270 if ( fPos1
> fXMax
)
1273 SetAdjustValueAsDouble( fPos1
, nFirstAdjustmentValue
);
1277 if ( aHandle
.nFlags
& HANDLE_FLAGS_RANGE_Y_MINIMUM
) // check if vertical handle needs to be within a range
1280 GetParameter( fYMin
, aHandle
.aYRangeMinimum
, sal_False
, sal_False
);
1281 if ( fPos2
< fYMin
)
1284 if ( aHandle
.nFlags
& HANDLE_FLAGS_RANGE_Y_MAXIMUM
) // check if vertical handle needs to be within a range
1287 GetParameter( fYMax
, aHandle
.aYRangeMaximum
, sal_False
, sal_False
);
1288 if ( fPos2
> fYMax
)
1291 SetAdjustValueAsDouble( fPos2
, nSecondAdjustmentValue
);
1294 // and writing them back into the GeometryItem
1295 SdrCustomShapeGeometryItem
aGeometryItem((SdrCustomShapeGeometryItem
&)
1296 (const SdrCustomShapeGeometryItem
&)pCustomShapeObj
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
));
1297 const rtl::OUString
sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
1298 com::sun::star::beans::PropertyValue aPropVal
;
1299 aPropVal
.Name
= sAdjustmentValues
;
1300 aPropVal
.Value
<<= seqAdjustmentValues
;
1301 aGeometryItem
.SetPropertyValue( aPropVal
);
1302 pCustomShapeObj
->SetMergedItem( aGeometryItem
);
1303 bRetValue
= sal_True
;
1310 void EnhancedCustomShape2d::SwapStartAndEndArrow( SdrObject
* pObj
) //#108274
1312 XLineStartItem aLineStart
;
1313 aLineStart
.SetLineStartValue(((XLineStartItem
&)pObj
->GetMergedItem( XATTR_LINEEND
)).GetLineStartValue());
1314 XLineStartWidthItem
aLineStartWidth(((XLineStartWidthItem
&)pObj
->GetMergedItem( XATTR_LINEENDWIDTH
)).GetValue());
1315 XLineStartCenterItem
aLineStartCenter(((XLineStartCenterItem
&)pObj
->GetMergedItem( XATTR_LINEENDCENTER
)).GetValue());
1317 XLineEndItem aLineEnd
;
1318 aLineEnd
.SetLineEndValue(((XLineEndItem
&)pObj
->GetMergedItem( XATTR_LINESTART
)).GetLineEndValue());
1319 XLineEndWidthItem
aLineEndWidth(((XLineEndWidthItem
&)pObj
->GetMergedItem( XATTR_LINESTARTWIDTH
)).GetValue());
1320 XLineEndCenterItem
aLineEndCenter(((XLineEndCenterItem
&)pObj
->GetMergedItem( XATTR_LINESTARTCENTER
)).GetValue());
1322 pObj
->SetMergedItem( aLineStart
);
1323 pObj
->SetMergedItem( aLineStartWidth
);
1324 pObj
->SetMergedItem( aLineStartCenter
);
1325 pObj
->SetMergedItem( aLineEnd
);
1326 pObj
->SetMergedItem( aLineEndWidth
);
1327 pObj
->SetMergedItem( aLineEndCenter
);
1330 basegfx::B2DPolygon
CreateArc( const Rectangle
& rRect
, const Point
& rStart
, const Point
& rEnd
, const sal_Bool bClockwise
)
1332 Rectangle
aRect( rRect
);
1333 Point
aStart( rStart
);
1336 sal_Int32 bSwapStartEndAngle
= 0;
1338 if ( aRect
.Left() > aRect
.Right() )
1339 bSwapStartEndAngle
^= 0x01;
1340 if ( aRect
.Top() > aRect
.Bottom() )
1341 bSwapStartEndAngle
^= 0x11;
1342 if ( bSwapStartEndAngle
)
1345 if ( bSwapStartEndAngle
& 1 )
1347 Point
aTmp( aStart
);
1353 Polygon
aTempPoly( aRect
, aStart
, aEnd
, POLY_ARC
);
1354 basegfx::B2DPolygon aRetval
;
1358 for ( sal_uInt16 j
= aTempPoly
.GetSize(); j
--; )
1360 aRetval
.append(basegfx::B2DPoint(aTempPoly
[ j
].X(), aTempPoly
[ j
].Y()));
1365 for ( sal_uInt16 j
= 0; j
< aTempPoly
.GetSize(); j
++ )
1367 aRetval
.append(basegfx::B2DPoint(aTempPoly
[ j
].X(), aTempPoly
[ j
].Y()));
1374 void EnhancedCustomShape2d::CreateSubPath( sal_uInt16
& rSrcPt
, sal_uInt16
& rSegmentInd
, std::vector
< SdrPathObj
* >& rObjectList
,
1375 const sal_Bool bLineGeometryNeededOnly
,
1376 const sal_Bool bSortFilledObjectsToBack
)
1378 sal_Bool bNoFill
= sal_False
;
1379 sal_Bool bNoStroke
= sal_False
;
1381 basegfx::B2DPolyPolygon aNewB2DPolyPolygon
;
1382 basegfx::B2DPolygon aNewB2DPolygon
;
1384 sal_Int32 nCoordSize
= seqCoordinates
.getLength();
1385 sal_Int32 nSegInfoSize
= seqSegments
.getLength();
1386 if ( !nSegInfoSize
)
1388 const EnhancedCustomShapeParameterPair
* pTmp
= seqCoordinates
.getArray();
1390 for ( sal_Int32
nPtNum(0L); nPtNum
< nCoordSize
; nPtNum
++ )
1392 const Point
aTempPoint(GetPoint( *pTmp
++, sal_True
, sal_True
));
1393 aNewB2DPolygon
.append(basegfx::B2DPoint(aTempPoint
.X(), aTempPoint
.Y()));
1396 aNewB2DPolygon
.setClosed(true);
1400 for ( ;rSegmentInd
< nSegInfoSize
; )
1402 sal_Int16 nCommand
= seqSegments
[ rSegmentInd
].Command
;
1403 sal_Int16 nPntCount
= seqSegments
[ rSegmentInd
++ ].Count
;
1411 bNoStroke
= sal_True
;
1415 if(aNewB2DPolygon
.count() > 1L)
1417 // #i76201# Add conversion to closed polygon when first and last points are equal
1418 basegfx::tools::checkClosed(aNewB2DPolygon
);
1419 aNewB2DPolyPolygon
.append(aNewB2DPolygon
);
1422 aNewB2DPolygon
.clear();
1424 if ( rSrcPt
< nCoordSize
)
1426 const Point
aTempPoint(GetPoint( seqCoordinates
[ rSrcPt
++ ], sal_True
, sal_True
));
1427 aNewB2DPolygon
.append(basegfx::B2DPoint(aTempPoint
.X(), aTempPoint
.Y()));
1435 if(aNewB2DPolygon
.count())
1437 if(aNewB2DPolygon
.count() > 1L)
1439 aNewB2DPolygon
.setClosed(true);
1440 aNewB2DPolyPolygon
.append(aNewB2DPolygon
);
1443 aNewB2DPolygon
.clear();
1449 for ( sal_uInt16 i
= 0; ( i
< nPntCount
) && ( ( rSrcPt
+ 2 ) < nCoordSize
); i
++ )
1451 const Point
aControlA(GetPoint( seqCoordinates
[ rSrcPt
++ ], sal_True
, sal_True
));
1452 const Point
aControlB(GetPoint( seqCoordinates
[ rSrcPt
++ ], sal_True
, sal_True
));
1453 const Point
aEnd(GetPoint( seqCoordinates
[ rSrcPt
++ ], sal_True
, sal_True
));
1455 DBG_ASSERT(aNewB2DPolygon
.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding control point (!)");
1456 aNewB2DPolygon
.appendBezierSegment(
1457 basegfx::B2DPoint(aControlA
.X(), aControlA
.Y()),
1458 basegfx::B2DPoint(aControlB
.X(), aControlB
.Y()),
1459 basegfx::B2DPoint(aEnd
.X(), aEnd
.Y()));
1466 if(aNewB2DPolygon
.count() > 1L)
1468 // #i76201# Add conversion to closed polygon when first and last points are equal
1469 basegfx::tools::checkClosed(aNewB2DPolygon
);
1470 aNewB2DPolyPolygon
.append(aNewB2DPolygon
);
1473 aNewB2DPolygon
.clear();
1475 case ANGLEELLIPSETO
:
1477 for ( sal_uInt16 i
= 0; ( i
< nPntCount
) && ( ( rSrcPt
+ 2 ) < nCoordSize
); i
++ )
1480 Point
_aCenter( GetPoint( seqCoordinates
[ rSrcPt
], sal_True
, sal_True
) );
1481 double fWidth
, fHeight
;
1482 GetParameter( fWidth
, seqCoordinates
[ rSrcPt
+ 1 ].First
, sal_True
, sal_False
);
1483 GetParameter( fHeight
, seqCoordinates
[ rSrcPt
+ 1 ].Second
, sal_False
, sal_True
);
1486 Point
aP( (sal_Int32
)( _aCenter
.X() - fWidth
), (sal_Int32
)( _aCenter
.Y() - fHeight
) );
1487 Size
aS( (sal_Int32
)( fWidth
* 2.0 ), (sal_Int32
)( fHeight
* 2.0 ) );
1488 Rectangle
aRect( aP
, aS
);
1489 if ( aRect
.GetWidth() && aRect
.GetHeight() )
1491 double fStartAngle
, fEndAngle
;
1492 GetParameter( fStartAngle
, seqCoordinates
[ rSrcPt
+ 2 ].First
, sal_False
, sal_False
);
1493 GetParameter( fEndAngle
, seqCoordinates
[ rSrcPt
+ 2 ].Second
, sal_False
, sal_False
);
1495 if ( ((sal_Int32
)fStartAngle
% 360) != ((sal_Int32
)fEndAngle
% 360) )
1497 if ( (sal_Int32
)fStartAngle
& 0x7fff0000 ) // SJ: if the angle was imported from our escher import, then the
1498 fStartAngle
/= 65536.0; // value is shifted by 16. TODO: already change the fixed float to a
1499 if ( (sal_Int32
)fEndAngle
& 0x7fff0000 ) // double in the import filter
1501 fEndAngle
/= 65536.0;
1502 fEndAngle
= fEndAngle
+ fStartAngle
;
1503 if ( fEndAngle
< 0 )
1504 { // in the binary filter the endangle is the amount
1505 double fTemp
= fStartAngle
;
1506 fStartAngle
= fEndAngle
;
1510 double fCenterX
= aRect
.Center().X();
1511 double fCenterY
= aRect
.Center().Y();
1512 double fx1
= ( cos( fStartAngle
* F_PI180
) * 65536.0 * fXScale
) + fCenterX
;
1513 double fy1
= ( -sin( fStartAngle
* F_PI180
) * 65536.0 * fYScale
) + fCenterY
;
1514 double fx2
= ( cos( fEndAngle
* F_PI180
) * 65536.0 * fXScale
) + fCenterX
;
1515 double fy2
= ( -sin( fEndAngle
* F_PI180
) * 65536.0 * fYScale
) + fCenterY
;
1516 aNewB2DPolygon
.append(CreateArc( aRect
, Point( (sal_Int32
)fx1
, (sal_Int32
)fy1
), Point( (sal_Int32
)fx2
, (sal_Int32
)fy2
), sal_False
));
1519 { /* SJ: TODO: this block should be replaced sometimes, because the current point
1520 is not set correct, it also does not use the correct moveto
1521 point if ANGLEELLIPSETO was used, but the method CreateArc
1522 is at the moment not able to draw full circles (if startangle is 0
1523 and endangle 360 nothing is painted :-( */
1524 sal_Int32 nXControl
= (sal_Int32
)((double)aRect
.GetWidth() * 0.2835 );
1525 sal_Int32 nYControl
= (sal_Int32
)((double)aRect
.GetHeight() * 0.2835 );
1526 Point
aCenter( aRect
.Center() );
1528 // append start point
1529 aNewB2DPolygon
.append(basegfx::B2DPoint(aCenter
.X(), aRect
.Top()));
1531 // append four bezier segments
1532 aNewB2DPolygon
.appendBezierSegment(
1533 basegfx::B2DPoint(aCenter
.X() + nXControl
, aRect
.Top()),
1534 basegfx::B2DPoint(aRect
.Right(), aCenter
.Y() - nYControl
),
1535 basegfx::B2DPoint(aRect
.Right(), aCenter
.Y()));
1537 aNewB2DPolygon
.appendBezierSegment(
1538 basegfx::B2DPoint(aRect
.Right(), aCenter
.Y() + nYControl
),
1539 basegfx::B2DPoint(aCenter
.X() + nXControl
, aRect
.Bottom()),
1540 basegfx::B2DPoint(aCenter
.X(), aRect
.Bottom()));
1542 aNewB2DPolygon
.appendBezierSegment(
1543 basegfx::B2DPoint(aCenter
.X() - nXControl
, aRect
.Bottom()),
1544 basegfx::B2DPoint(aRect
.Left(), aCenter
.Y() + nYControl
),
1545 basegfx::B2DPoint(aRect
.Left(), aCenter
.Y()));
1547 aNewB2DPolygon
.appendBezierSegment(
1548 basegfx::B2DPoint(aRect
.Left(), aCenter
.Y() - nYControl
),
1549 basegfx::B2DPoint(aCenter
.X() - nXControl
, aRect
.Top()),
1550 basegfx::B2DPoint(aCenter
.X(), aRect
.Top()));
1552 // close, rescue last controlpoint, remove double last point
1553 basegfx::tools::closeWithGeometryChange(aNewB2DPolygon
);
1563 for ( sal_Int32
i(0L); ( i
< nPntCount
) && ( rSrcPt
< nCoordSize
); i
++ )
1565 const Point
aTempPoint(GetPoint( seqCoordinates
[ rSrcPt
++ ], sal_True
, sal_True
));
1566 aNewB2DPolygon
.append(basegfx::B2DPoint(aTempPoint
.X(), aTempPoint
.Y()));
1574 if(aNewB2DPolygon
.count() > 1L)
1576 // #i76201# Add conversion to closed polygon when first and last points are equal
1577 basegfx::tools::checkClosed(aNewB2DPolygon
);
1578 aNewB2DPolyPolygon
.append(aNewB2DPolygon
);
1581 aNewB2DPolygon
.clear();
1584 case CLOCKWISEARCTO
:
1586 sal_Bool bClockwise
= ( nCommand
== CLOCKWISEARC
) || ( nCommand
== CLOCKWISEARCTO
);
1587 sal_uInt32 nXor
= bClockwise
? 3 : 2;
1588 for ( sal_uInt16 i
= 0; ( i
< nPntCount
) && ( ( rSrcPt
+ 3 ) < nCoordSize
); i
++ )
1590 Rectangle
aRect( GetPoint( seqCoordinates
[ rSrcPt
], sal_True
, sal_True
), GetPoint( seqCoordinates
[ rSrcPt
+ 1 ], sal_True
, sal_True
) );
1591 if ( aRect
.GetWidth() && aRect
.GetHeight() )
1593 Point
aCenter( aRect
.Center() );
1594 Point
aStart( GetPoint( seqCoordinates
[ (sal_uInt16
)( rSrcPt
+ nXor
) ], sal_True
, sal_True
) );
1595 Point
aEnd( GetPoint( seqCoordinates
[ (sal_uInt16
)( rSrcPt
+ ( nXor
^ 1 ) ) ], sal_True
, sal_True
) );
1596 double fRatio
= (double)aRect
.GetHeight() / (double)aRect
.GetWidth();
1597 aStart
.X() = (sal_Int32
)( ( (double)( aStart
.X() - aCenter
.X() ) ) * fRatio
) + aCenter
.X();
1598 aStart
.Y() = (sal_Int32
)( ( (double)( aStart
.Y() - aCenter
.Y() ) ) ) + aCenter
.Y();
1599 aEnd
.X() = (sal_Int32
)( ( (double)( aEnd
.X() - aCenter
.X() ) ) * fRatio
) + aCenter
.X();
1600 aEnd
.Y() = (sal_Int32
)( ( (double)( aEnd
.Y() - aCenter
.Y() ) ) ) + aCenter
.Y();
1601 aNewB2DPolygon
.append(CreateArc( aRect
, aStart
, aEnd
, bClockwise
));
1608 case ELLIPTICALQUADRANTX
:
1609 case ELLIPTICALQUADRANTY
:
1611 bool bFirstDirection(true);
1612 basegfx::B2DPoint aControlPointA
;
1613 basegfx::B2DPoint aControlPointB
;
1615 for ( sal_uInt16 i
= 0; ( i
< nPntCount
) && ( rSrcPt
< nCoordSize
); i
++ )
1617 sal_uInt32 nModT
= ( nCommand
== ELLIPTICALQUADRANTX
) ? 1 : 0;
1618 Point
aCurrent( GetPoint( seqCoordinates
[ rSrcPt
], sal_True
, sal_True
) );
1620 if ( rSrcPt
) // we need a previous point
1622 Point
aPrev( GetPoint( seqCoordinates
[ rSrcPt
- 1 ], sal_True
, sal_True
) );
1624 nX
= aCurrent
.X() - aPrev
.X();
1625 nY
= aCurrent
.Y() - aPrev
.Y();
1626 if ( ( nY
^ nX
) & 0x80000000 )
1629 bFirstDirection
= true;
1630 else if ( !bFirstDirection
)
1636 bFirstDirection
= false;
1637 else if ( bFirstDirection
)
1640 if ( nModT
) // get the right corner
1650 sal_Int32 nXVec
= ( nX
- aPrev
.X() ) >> 1;
1651 sal_Int32 nYVec
= ( nY
- aPrev
.Y() ) >> 1;
1652 Point
aControl1( aPrev
.X() + nXVec
, aPrev
.Y() + nYVec
);
1654 aControlPointA
= basegfx::B2DPoint(aControl1
.X(), aControl1
.Y());
1656 nXVec
= ( nX
- aCurrent
.X() ) >> 1;
1657 nYVec
= ( nY
- aCurrent
.Y() ) >> 1;
1658 Point
aControl2( aCurrent
.X() + nXVec
, aCurrent
.Y() + nYVec
);
1660 aControlPointB
= basegfx::B2DPoint(aControl2
.X(), aControl2
.Y());
1662 aNewB2DPolygon
.appendBezierSegment(
1665 basegfx::B2DPoint(aCurrent
.X(), aCurrent
.Y()));
1669 aNewB2DPolygon
.append(basegfx::B2DPoint(aCurrent
.X(), aCurrent
.Y()));
1677 #ifdef DBG_CUSTOMSHAPE
1681 ByteString
aString( "CustomShapes::unknown PolyFlagValue :" );
1682 aString
.Append( ByteString::CreateFromInt32( nCommand
) );
1683 DBG_ERROR( aString
.GetBuffer() );
1688 if ( nCommand
== ENDSUBPATH
)
1692 if ( rSegmentInd
== nSegInfoSize
)
1695 if(aNewB2DPolygon
.count() > 1L)
1697 // #i76201# Add conversion to closed polygon when first and last points are equal
1698 basegfx::tools::checkClosed(aNewB2DPolygon
);
1699 aNewB2DPolyPolygon
.append(aNewB2DPolygon
);
1702 if(aNewB2DPolyPolygon
.count())
1704 if( !bLineGeometryNeededOnly
)
1706 // hack aNewB2DPolyPolygon to fill logic rect - this is
1707 // needed to produce gradient fills that look like mso
1708 aNewB2DPolygon
.clear();
1709 aNewB2DPolygon
.append(basegfx::B2DPoint(0,0));
1710 aNewB2DPolyPolygon
.append(aNewB2DPolygon
);
1712 aNewB2DPolygon
.clear();
1713 aNewB2DPolygon
.append(basegfx::B2DPoint(aLogicRect
.GetWidth(),
1714 aLogicRect
.GetHeight()));
1715 aNewB2DPolyPolygon
.append(aNewB2DPolygon
);
1718 bool bForceCreateTwoObjects(false);
1720 if(!bSortFilledObjectsToBack
&& !aNewB2DPolyPolygon
.isClosed() && !bNoStroke
)
1722 bForceCreateTwoObjects
= true;
1725 if(bLineGeometryNeededOnly
)
1727 bForceCreateTwoObjects
= true;
1732 if(bForceCreateTwoObjects
|| bSortFilledObjectsToBack
)
1734 if(bFilled
&& !bNoFill
)
1736 basegfx::B2DPolyPolygon
aClosedPolyPolygon(aNewB2DPolyPolygon
);
1737 aClosedPolyPolygon
.setClosed(true);
1738 SdrPathObj
* pFill
= new SdrPathObj(OBJ_POLY
, aClosedPolyPolygon
);
1739 SfxItemSet
aTempSet(*this);
1740 aTempSet
.Put(SdrShadowItem(sal_False
));
1741 aTempSet
.Put(XLineStyleItem(XLINE_NONE
));
1742 pFill
->SetMergedItemSet(aTempSet
);
1743 rObjectList
.push_back(pFill
);
1748 // there is no reason to use OBJ_PLIN here when the polygon is actually closed,
1749 // the non-fill is defined by XFILL_NONE. Since SdrPathObj::ImpForceKind() needs
1750 // to correct the polygon (here: open it) using the type, the last edge may get lost.
1751 // Thus, use a type that fits the polygon
1752 SdrPathObj
* pStroke
= new SdrPathObj(
1753 aNewB2DPolyPolygon
.isClosed() ? OBJ_POLY
: OBJ_PLIN
,
1754 aNewB2DPolyPolygon
);
1755 SfxItemSet
aTempSet(*this);
1756 aTempSet
.Put(SdrShadowItem(sal_False
));
1757 aTempSet
.Put(XFillStyleItem(XFILL_NONE
));
1758 pStroke
->SetMergedItemSet(aTempSet
);
1759 rObjectList
.push_back(pStroke
);
1764 SdrPathObj
* pObj
= 0;
1765 SfxItemSet
aTempSet(*this);
1766 aTempSet
.Put(SdrShadowItem(sal_False
));
1770 // see comment above about OBJ_PLIN
1771 pObj
= new SdrPathObj(
1772 aNewB2DPolyPolygon
.isClosed() ? OBJ_POLY
: OBJ_PLIN
,
1773 aNewB2DPolyPolygon
);
1774 aTempSet
.Put(XFillStyleItem(XFILL_NONE
));
1778 aNewB2DPolyPolygon
.setClosed(true);
1779 pObj
= new SdrPathObj(OBJ_POLY
, aNewB2DPolyPolygon
);
1784 aTempSet
.Put(XLineStyleItem(XLINE_NONE
));
1789 pObj
->SetMergedItemSet(aTempSet
);
1790 rObjectList
.push_back(pObj
);
1796 void CorrectCalloutArrows( MSO_SPT eSpType
, sal_uInt32 nLineObjectCount
, std::vector
< SdrPathObj
* >& vObjectList
)
1798 sal_Bool bAccent
= sal_False
;
1801 case mso_sptCallout1
:
1802 case mso_sptBorderCallout1
:
1803 case mso_sptCallout90
:
1804 case mso_sptBorderCallout90
:
1808 case mso_sptAccentCallout1
:
1809 case mso_sptAccentBorderCallout1
:
1810 case mso_sptAccentCallout90
:
1811 case mso_sptAccentBorderCallout90
:
1813 sal_uInt32 i
, nLine
= 0;
1814 for ( i
= 0; i
< vObjectList
.size(); i
++ )
1816 SdrPathObj
* pObj( vObjectList
[ i
] );
1820 if ( nLine
== nLineObjectCount
)
1822 pObj
->ClearMergedItem( XATTR_LINESTART
);
1823 pObj
->ClearMergedItem( XATTR_LINEEND
);
1830 // switch start & end
1831 case mso_sptAccentCallout2
:
1832 case mso_sptAccentBorderCallout2
:
1834 case mso_sptCallout2
:
1835 case mso_sptBorderCallout2
:
1837 sal_uInt32 i
, nLine
= 0;
1838 for ( i
= 0; i
< vObjectList
.size(); i
++ )
1840 SdrPathObj
* pObj( vObjectList
[ i
] );
1845 pObj
->ClearMergedItem( XATTR_LINEEND
);
1846 else if ( ( bAccent
&& ( nLine
== nLineObjectCount
- 1 ) ) || ( !bAccent
&& ( nLine
== nLineObjectCount
) ) )
1847 pObj
->ClearMergedItem( XATTR_LINESTART
);
1850 pObj
->ClearMergedItem( XATTR_LINESTART
);
1851 pObj
->ClearMergedItem( XATTR_LINEEND
);
1858 case mso_sptAccentCallout3
:
1859 case mso_sptAccentBorderCallout3
:
1860 bAccent
= sal_False
;
1861 case mso_sptCallout3
:
1862 case mso_sptBorderCallout3
:
1864 sal_uInt32 i
, nLine
= 0;
1865 for ( i
= 0; i
< vObjectList
.size(); i
++ )
1867 SdrPathObj
* pObj( vObjectList
[ i
] );
1872 pObj
->ClearMergedItem( XATTR_LINESTART
);
1873 pObj
->ClearMergedItem( XATTR_LINEEND
);
1876 EnhancedCustomShape2d::SwapStartAndEndArrow( pObj
);
1886 void EnhancedCustomShape2d::AdaptObjColor(SdrPathObj
& rObj
, const SfxItemSet
& rCustomShapeSet
,
1887 sal_uInt32
& nColorIndex
, sal_uInt32 nColorCount
)
1889 if ( !rObj
.IsLine() )
1891 const XFillStyle eFillStyle
= ((const XFillStyleItem
&)rObj
.GetMergedItem(XATTR_FILLSTYLE
)).GetValue();
1892 switch( eFillStyle
)
1900 aFillColor
= GetColorData(
1901 ((XFillColorItem
&)rCustomShapeSet
.Get( XATTR_FILLCOLOR
)).GetColorValue(),
1902 std::min(nColorIndex
, nColorCount
-1) );
1903 rObj
.SetMergedItem( XFillColorItem( String(), aFillColor
) );
1907 case XFILL_GRADIENT
:
1909 XGradient
aXGradient(((const XFillGradientItem
&)rObj
.GetMergedItem(XATTR_FILLGRADIENT
)).GetGradientValue());
1912 aXGradient
.SetStartColor(
1914 aXGradient
.GetStartColor(),
1915 std::min(nColorIndex
, nColorCount
-1) ));
1916 aXGradient
.SetEndColor(
1918 aXGradient
.GetEndColor(),
1919 std::min(nColorIndex
, nColorCount
-1) ));
1922 rObj
.SetMergedItem( XFillGradientItem( String(), aXGradient
) );
1927 XHatch
aXHatch(((const XFillHatchItem
&)rObj
.GetMergedItem(XATTR_FILLHATCH
)).GetHatchValue());
1933 std::min(nColorIndex
, nColorCount
-1) ));
1936 rObj
.SetMergedItem( XFillHatchItem( String(), aXHatch
) );
1941 Bitmap
aBitmap(((const XFillBitmapItem
&)rObj
.GetMergedItem(XATTR_FILLBITMAP
)).GetBitmapValue().GetBitmap());
1945 static_cast< short > ( GetLuminanceChange(
1946 std::min(nColorIndex
, nColorCount
-1))));
1949 rObj
.SetMergedItem( XFillBitmapItem( String(), aBitmap
) );
1954 if ( nColorIndex
< nColorCount
)
1959 SdrObject
* EnhancedCustomShape2d::CreatePathObj( sal_Bool bLineGeometryNeededOnly
)
1961 sal_Int32 nCoordSize
= seqCoordinates
.getLength();
1965 sal_uInt16 nSrcPt
= 0;
1966 sal_uInt16 nSegmentInd
= 0;
1968 std::vector
< SdrPathObj
* > vObjectList
;
1969 sal_Bool bSortFilledObjectsToBack
= SortFilledObjectsToBackByDefault( eSpType
);
1971 while( nSegmentInd
<= seqSegments
.getLength() )
1973 CreateSubPath( nSrcPt
, nSegmentInd
, vObjectList
, bLineGeometryNeededOnly
, bSortFilledObjectsToBack
);
1976 SdrObject
* pRet
= NULL
;
1979 if ( vObjectList
.size() )
1981 const SfxItemSet
& rCustomShapeSet
= pCustomShapeObj
->GetMergedItemSet();
1983 sal_uInt32 nColorCount
= nColorData
>> 28;
1984 sal_uInt32 nColorIndex
= 0;
1986 // #i37011# remove invisible objects
1987 if(vObjectList
.size())
1989 std::vector
< SdrPathObj
* > vTempList
;
1991 for(i
= 0L; i
< vObjectList
.size(); i
++)
1993 SdrPathObj
* pObj(vObjectList
[i
]);
1994 const XLineStyle eLineStyle
= ((const XLineStyleItem
&)pObj
->GetMergedItem(XATTR_LINESTYLE
)).GetValue();
1995 const XFillStyle eFillStyle
= ((const XFillStyleItem
&)pObj
->GetMergedItem(XATTR_FILLSTYLE
)).GetValue();
1997 //SJ: #i40600# if bLineGeometryNeededOnly is set linystyle does not matter
1998 if( !bLineGeometryNeededOnly
&& ( XLINE_NONE
== eLineStyle
) && ( XFILL_NONE
== eFillStyle
) )
2001 vTempList
.push_back(pObj
);
2004 vObjectList
= vTempList
;
2007 if(1L == vObjectList
.size())
2009 // a single object, correct some values
2010 AdaptObjColor(*vObjectList
[0L],rCustomShapeSet
,nColorIndex
,nColorCount
);
2014 sal_Int32 nLineObjectCount
= 0;
2015 sal_Int32 nAreaObjectCount
= 0;
2017 // correct some values and collect content data
2018 for ( i
= 0; i
< vObjectList
.size(); i
++ )
2020 SdrPathObj
* pObj( vObjectList
[ i
] );
2029 AdaptObjColor(*pObj
,rCustomShapeSet
,nColorIndex
,nColorCount
);
2033 // #i88870# correct line arrows for callouts
2034 if ( nLineObjectCount
)
2035 CorrectCalloutArrows( eSpType
, nLineObjectCount
, vObjectList
);
2037 // sort objects so that filled ones are in front. Necessary
2038 // for some strange objects
2039 if ( bSortFilledObjectsToBack
)
2041 std::vector
< SdrPathObj
* > vTempList
;
2043 for ( i
= 0; i
< vObjectList
.size(); i
++ )
2045 SdrPathObj
* pObj( vObjectList
[ i
] );
2047 if ( !pObj
->IsLine() )
2049 vTempList
.push_back(pObj
);
2053 for ( i
= 0; i
< vObjectList
.size(); i
++ )
2055 SdrPathObj
* pObj( vObjectList
[ i
] );
2057 if ( pObj
->IsLine() )
2059 vTempList
.push_back(pObj
);
2063 vObjectList
= vTempList
;
2069 if(vObjectList
.size())
2071 // copy remaining objects to pRet
2072 if(vObjectList
.size() > 1L)
2074 pRet
= new SdrObjGroup
;
2076 for (i
= 0L; i
< vObjectList
.size(); i
++)
2078 SdrObject
* pObj(vObjectList
[i
]);
2079 pRet
->GetSubList()->NbcInsertObject(pObj
);
2082 else if(1L == vObjectList
.size())
2084 pRet
= vObjectList
[0L];
2089 // move to target position
2090 Rectangle
aCurRect(pRet
->GetSnapRect());
2091 aCurRect
.Move(aLogicRect
.Left(), aLogicRect
.Top());
2092 pRet
->NbcSetSnapRect(aCurRect
);
2099 SdrObject
* EnhancedCustomShape2d::CreateObject( sal_Bool bLineGeometryNeededOnly
)
2101 SdrObject
* pRet
= NULL
;
2103 if ( eSpType
== mso_sptRectangle
)
2105 pRet
= new SdrRectObj( aLogicRect
);
2106 // SJ: not setting model, so we save a lot of broadcasting and the model is not modified any longer
2107 // pRet->SetModel( pCustomShapeObj->GetModel() );
2108 pRet
->SetMergedItemSet( *this );
2111 pRet
= CreatePathObj( bLineGeometryNeededOnly
);
2116 void EnhancedCustomShape2d::ApplyGluePoints( SdrObject
* pObj
)
2118 if ( pObj
&& seqGluePoints
.getLength() )
2120 sal_uInt32 i
, nCount
= seqGluePoints
.getLength();
2121 for ( i
= 0; i
< nCount
; i
++ )
2123 SdrGluePoint aGluePoint
;
2125 aGluePoint
.SetPos( GetPoint( seqGluePoints
[ i
], sal_True
, sal_True
) );
2126 aGluePoint
.SetPercent( sal_False
);
2128 // const Point& rPoint = GetPoint( seqGluePoints[ i ], sal_True, sal_True );
2129 // double fXRel = rPoint.X();
2130 // double fYRel = rPoint.Y();
2131 // fXRel = aLogicRect.GetWidth() == 0 ? 0.0 : fXRel / aLogicRect.GetWidth() * 10000;
2132 // fYRel = aLogicRect.GetHeight() == 0 ? 0.0 : fYRel / aLogicRect.GetHeight() * 10000;
2133 // aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
2134 // aGluePoint.SetPercent( sal_True );
2135 aGluePoint
.SetAlign( SDRVERTALIGN_TOP
| SDRHORZALIGN_LEFT
);
2136 aGluePoint
.SetEscDir( SDRESC_SMART
);
2137 SdrGluePointList
* pList
= pObj
->ForceGluePointList();
2139 /* sal_uInt16 nId = */ pList
->Insert( aGluePoint
);
2144 SdrObject
* EnhancedCustomShape2d::CreateLineGeometry()
2146 return CreateObject( sal_True
);