1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 #include "svx/EnhancedCustomShape2d.hxx" 27 #include "svx/EnhancedCustomShapeGeometry.hxx" 28 #include "svx/EnhancedCustomShapeTypeNames.hxx" 29 #include <svx/svdoashp.hxx> 30 #include <svx/svdtrans.hxx> 31 #include <svx/svdocirc.hxx> 32 #include <svx/svdogrp.hxx> 33 #include <svx/svdopath.hxx> 34 #ifndef _SVDOCAPT_HXX 35 #include <svx/svdocapt.hxx> 36 #endif 37 #include <svx/svdpage.hxx> 38 #include <svx/xflclit.hxx> 39 #include <svx/sdasaitm.hxx> 40 #include <svx/svdmodel.hxx> 41 #include <rtl/crc.h> 42 #include <rtl/math.hxx> 43 #include <svx/xfillit0.hxx> 44 #include <svx/xlnstit.hxx> 45 #include <svx/xlnedit.hxx> 46 #include <svx/xlnstwit.hxx> 47 #include <svx/xlnedwit.hxx> 48 #include <svx/xlnstcit.hxx> 49 #include <svx/xlnedcit.hxx> 50 #include <svx/xflgrit.hxx> 51 #include <svx/xflhtit.hxx> 52 #include <svx/xbtmpit.hxx> 53 #include <svx/xgrad.hxx> 54 #include <svx/xbitmap.hxx> 55 #include <svx/xhatch.hxx> 56 #include <com/sun/star/awt/Size.hpp> 57 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp> 58 #ifndef __COM_SUN_STAR_DRAWING_ENHANCEDCUSTOMSHAPESEGMENTCOMMAND_HPP__ 59 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp> 60 #endif 61 #ifndef BOOST_SHARED_PTR_HPP_INCLUDED 62 #include <boost/shared_ptr.hpp> 63 #endif 64 #include <basegfx/numeric/ftools.hxx> 65 #include <basegfx/color/bcolortools.hxx> 66 #include <basegfx/polygon/b2dpolygon.hxx> 67 68 // #i76201# 69 #include <basegfx/polygon/b2dpolygontools.hxx> 70 71 #include <math.h> 72 73 using namespace ::com::sun::star::uno; 74 using namespace ::com::sun::star::drawing; 75 using namespace ::com::sun::star::drawing::EnhancedCustomShapeSegmentCommand; 76 77 void EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nValue ) 78 { 79 sal_uInt32 nDat = (sal_uInt32)nValue; 80 sal_Int32 nNewValue = nValue; 81 82 // check if this is a special point 83 if ( ( nDat >> 16 ) == 0x8000 ) 84 { 85 nNewValue = (sal_uInt16)nDat; 86 rParameter.Type = EnhancedCustomShapeParameterType::EQUATION; 87 } 88 else 89 rParameter.Type = EnhancedCustomShapeParameterType::NORMAL; 90 rParameter.Value <<= nNewValue; 91 } 92 93 rtl::OUString EnhancedCustomShape2d::GetEquation( const sal_uInt16 nFlags, sal_Int16 nP1, sal_Int16 nP2, sal_Int16 nP3 ) 94 { 95 rtl::OUString aEquation; 96 sal_Bool b1Special = ( nFlags & 0x2000 ) != 0; 97 sal_Bool b2Special = ( nFlags & 0x4000 ) != 0; 98 sal_Bool b3Special = ( nFlags & 0x8000 ) != 0; 99 switch( nFlags & 0xff ) 100 { 101 case 0 : 102 case 14 : 103 { 104 sal_Int32 nOptimize = 0; 105 if ( nP1 ) 106 nOptimize |= 1; 107 if ( nP2 ) 108 nOptimize |= 2; 109 if ( b1Special ) 110 nOptimize |= 4; 111 if ( b2Special ) 112 nOptimize |= 8; 113 switch( nOptimize ) 114 { 115 case 0 : 116 break; 117 case 1 : 118 case 4 : 119 case 5 : 120 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 121 break; 122 case 2 : 123 case 8 : 124 case 10: 125 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 126 break; 127 default : 128 { 129 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 130 aEquation += rtl::OUString( (sal_Unicode)'+' ); 131 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 132 } 133 break; 134 } 135 if ( b3Special || nP3 ) 136 { 137 aEquation += rtl::OUString( (sal_Unicode)'-' ); 138 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 139 } 140 } 141 break; 142 case 1 : 143 { 144 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 145 if ( b2Special || ( nP2 != 1 ) ) 146 { 147 aEquation += rtl::OUString( (sal_Unicode)'*' ); 148 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 149 } 150 if ( b3Special || ( ( nP3 != 1 ) && ( nP3 != 0 ) ) ) 151 { 152 aEquation += rtl::OUString( (sal_Unicode)'/' ); 153 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 154 } 155 } 156 break; 157 case 2 : 158 { 159 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "(" ) ); 160 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 161 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) ); 162 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 163 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")/2" ) ); 164 } 165 break; 166 case 3 : 167 { 168 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "abs(" ) ); 169 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 170 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) ); 171 } 172 break; 173 case 4 : 174 { 175 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "min(" ) ); 176 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 177 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) ); 178 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 179 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) ); 180 } 181 break; 182 case 5 : 183 { 184 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "max(" ) ); 185 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 186 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) ); 187 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 188 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) ); 189 } 190 break; 191 case 6 : 192 { 193 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "if(" ) ); 194 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 195 aEquation += rtl::OUString( (sal_Unicode)',' ); 196 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 197 aEquation += rtl::OUString( (sal_Unicode)',' ); 198 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 199 aEquation += rtl::OUString( (sal_Unicode)')' ); 200 } 201 break; 202 case 7 : 203 { 204 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) ); 205 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 206 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) ); 207 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 208 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) ); 209 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 210 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) ); 211 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 212 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "+" ) ); 213 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 214 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) ); 215 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 216 aEquation += rtl::OUString( (sal_Unicode)')' ); 217 } 218 break; 219 case 8 : 220 { 221 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "atan2(" ) ); 222 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 223 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) ); 224 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 225 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")/(pi/180)" ) ); 226 } 227 break; 228 case 9 : 229 { 230 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 231 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*sin(" ) ); 232 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 233 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))" ) ); 234 } 235 break; 236 case 10 : 237 { 238 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 239 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*cos(" ) ); 240 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 241 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))" ) ); 242 } 243 break; 244 case 11 : 245 { 246 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 247 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) ); 248 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "cos(atan2(" ) ); 249 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 250 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) ); 251 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 252 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) ); 253 } 254 break; 255 case 12 : 256 { 257 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 258 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) ); 259 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sin(atan2(" ) ); 260 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 261 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "," ) ); 262 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 263 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) ); 264 } 265 break; 266 case 13 : 267 { 268 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) ); 269 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 270 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) ); 271 } 272 break; 273 case 15 : 274 { 275 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 276 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*sqrt(1-(" ) ); 277 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 278 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) ); 279 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 280 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) ); 281 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(" ) ); 282 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 283 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "/" ) ); 284 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 285 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "))" ) ); 286 } 287 break; 288 case 16 : 289 { 290 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 291 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*tan(" ) ); 292 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 293 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( ")" ) ); 294 } 295 break; 296 case 0x80 : 297 { 298 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "sqrt(" ) ); 299 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 300 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) ); 301 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 302 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-" ) ); 303 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 304 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*" ) ); 305 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 306 aEquation += rtl::OUString( (sal_Unicode)')' ); 307 } 308 break; 309 case 0x81 : 310 { 311 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "(cos(" ) ); 312 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 313 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) ); 314 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 315 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800)+sin(" ) ); 316 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 317 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) ); 318 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 319 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800))+10800" ) ); 320 } 321 break; 322 case 0x82 : 323 { 324 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-(sin(" ) ); 325 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 326 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) ); 327 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP1, b1Special ); 328 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800)-cos(" ) ); 329 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP3, b3Special ); 330 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "*(pi/180))*(" ) ); 331 EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( aEquation, nP2, b2Special ); 332 aEquation += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "-10800))+10800" ) ); 333 } 334 break; 335 } 336 return aEquation; 337 } 338 339 void EnhancedCustomShape2d::AppendEnhancedCustomShapeEquationParameter( rtl::OUString& rParameter, const sal_Int16 nPara, const sal_Bool bIsSpecialValue ) 340 { 341 if ( bIsSpecialValue ) 342 { 343 if ( nPara & 0x400 ) 344 { 345 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "?" ) ); 346 rParameter += rtl::OUString::valueOf( (sal_Int32)( nPara & 0xff ) ); 347 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( " " ) ); 348 } 349 else 350 { 351 switch( nPara ) 352 { 353 case DFF_Prop_adjustValue : 354 case DFF_Prop_adjust2Value : 355 case DFF_Prop_adjust3Value : 356 case DFF_Prop_adjust4Value : 357 case DFF_Prop_adjust5Value : 358 case DFF_Prop_adjust6Value : 359 case DFF_Prop_adjust7Value : 360 case DFF_Prop_adjust8Value : 361 case DFF_Prop_adjust9Value : 362 case DFF_Prop_adjust10Value : 363 { 364 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "$" ) ); 365 rParameter += rtl::OUString::valueOf( (sal_Int32)( nPara - DFF_Prop_adjustValue ) ); 366 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( " " ) ); 367 } 368 break; 369 case DFF_Prop_geoLeft : 370 { 371 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "left" ) ); 372 } 373 break; 374 case DFF_Prop_geoTop : 375 { 376 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "top" ) ); 377 } 378 break; 379 case DFF_Prop_geoRight : 380 { 381 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "right" ) ); 382 } 383 break; 384 case DFF_Prop_geoBottom : 385 { 386 rParameter += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "bottom" ) ); 387 } 388 break; 389 } 390 } 391 } 392 else 393 { 394 rParameter += rtl::OUString::valueOf( (sal_Int32)( nPara ) ); 395 } 396 } 397 398 void EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( EnhancedCustomShapeParameter& rParameter, const sal_Int32 nPara, const sal_Bool bIsSpecialValue, sal_Bool bHorz ) 399 { 400 sal_Int32 nValue = 0; 401 if ( bIsSpecialValue ) 402 { 403 if ( ( nPara >= 0x100 ) && ( nPara <= 0x107 ) ) 404 { 405 nValue = nPara & 0xff; 406 rParameter.Type = EnhancedCustomShapeParameterType::ADJUSTMENT; 407 } 408 else if ( ( nPara >= 3 ) && ( nPara <= 0x82 ) ) 409 { 410 nValue = nPara - 3; 411 rParameter.Type = EnhancedCustomShapeParameterType::EQUATION; 412 } 413 else if ( nPara == 0 ) 414 { 415 nValue = 0; 416 if ( bHorz ) 417 rParameter.Type = EnhancedCustomShapeParameterType::LEFT; 418 else 419 rParameter.Type = EnhancedCustomShapeParameterType::TOP; 420 } 421 else if ( nPara == 1 ) 422 { 423 nValue = 0; 424 if ( bHorz ) 425 rParameter.Type = EnhancedCustomShapeParameterType::RIGHT; 426 else 427 rParameter.Type = EnhancedCustomShapeParameterType::BOTTOM; 428 } 429 else if ( nPara == 2 ) // means to be centered, but should not be 430 { // used in our implementation 431 nValue = 5600; 432 rParameter.Type = EnhancedCustomShapeParameterType::NORMAL; 433 } 434 else 435 { 436 nValue = nPara; 437 rParameter.Type = EnhancedCustomShapeParameterType::NORMAL; 438 } 439 } 440 else 441 { 442 nValue = nPara; 443 rParameter.Type = EnhancedCustomShapeParameterType::NORMAL; 444 } 445 rParameter.Value <<= nValue; 446 } 447 448 sal_Bool EnhancedCustomShape2d::ConvertSequenceToEnhancedCustomShape2dHandle( 449 const com::sun::star::beans::PropertyValues& rHandleProperties, 450 EnhancedCustomShape2d::Handle& rDestinationHandle ) 451 { 452 sal_Bool bRetValue = sal_False; 453 sal_uInt32 i, nProperties = rHandleProperties.getLength(); 454 if ( nProperties ) 455 { 456 rDestinationHandle.nFlags = 0; 457 for ( i = 0; i < nProperties; i++ ) 458 { 459 const com::sun::star::beans::PropertyValue& rPropVal = rHandleProperties[ i ]; 460 461 const rtl::OUString sPosition ( RTL_CONSTASCII_USTRINGPARAM( "Position" ) ); 462 const rtl::OUString sMirroredX ( RTL_CONSTASCII_USTRINGPARAM( "MirroredX" ) ); 463 const rtl::OUString sMirroredY ( RTL_CONSTASCII_USTRINGPARAM( "MirroredY" ) ); 464 const rtl::OUString sSwitched ( RTL_CONSTASCII_USTRINGPARAM( "Switched" ) ); 465 const rtl::OUString sPolar ( RTL_CONSTASCII_USTRINGPARAM( "Polar" ) ); 466 // const rtl::OUString sMap ( RTL_CONSTASCII_USTRINGPARAM( "Map" ) ); 467 const rtl::OUString sRefX ( RTL_CONSTASCII_USTRINGPARAM( "RefX" ) ); 468 const rtl::OUString sRefY ( RTL_CONSTASCII_USTRINGPARAM( "RefY" ) ); 469 const rtl::OUString sRefAngle ( RTL_CONSTASCII_USTRINGPARAM( "RefAngle" ) ); 470 const rtl::OUString sRefR ( RTL_CONSTASCII_USTRINGPARAM( "RefR" ) ); 471 const rtl::OUString sRadiusRangeMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMinimum" ) ); 472 const rtl::OUString sRadiusRangeMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMaximum" ) ); 473 const rtl::OUString sRangeXMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMinimum" ) ); 474 const rtl::OUString sRangeXMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMaximum" ) ); 475 const rtl::OUString sRangeYMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMinimum" ) ); 476 const rtl::OUString sRangeYMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMaximum" ) ); 477 478 if ( rPropVal.Name.equals( sPosition ) ) 479 { 480 if ( rPropVal.Value >>= rDestinationHandle.aPosition ) 481 bRetValue = sal_True; 482 } 483 else if ( rPropVal.Name.equals( sMirroredX ) ) 484 { 485 sal_Bool bMirroredX = sal_Bool(); 486 if ( rPropVal.Value >>= bMirroredX ) 487 { 488 if ( bMirroredX ) 489 rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_X; 490 } 491 } 492 else if ( rPropVal.Name.equals( sMirroredY ) ) 493 { 494 sal_Bool bMirroredY = sal_Bool(); 495 if ( rPropVal.Value >>= bMirroredY ) 496 { 497 if ( bMirroredY ) 498 rDestinationHandle.nFlags |= HANDLE_FLAGS_MIRRORED_Y; 499 } 500 } 501 else if ( rPropVal.Name.equals( sSwitched ) ) 502 { 503 sal_Bool bSwitched = sal_Bool(); 504 if ( rPropVal.Value >>= bSwitched ) 505 { 506 if ( bSwitched ) 507 rDestinationHandle.nFlags |= HANDLE_FLAGS_SWITCHED; 508 } 509 } 510 else if ( rPropVal.Name.equals( sPolar ) ) 511 { 512 if ( rPropVal.Value >>= rDestinationHandle.aPolar ) 513 rDestinationHandle.nFlags |= HANDLE_FLAGS_POLAR; 514 } 515 /* seems not to be used. 516 else if ( rPropVal.Name.equals( sMap ) ) 517 { 518 com::sun::star::drawing::EnhancedCustomShapeParameterPair aMap; 519 if ( rPropVal.Value >>= aMap ) 520 { 521 if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aMap.First ) ) 522 rDestinationHandle.Flags |= 0x800; 523 if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aMap.Second ) ) 524 rDestinationHandle.Flags |= 0x1000; 525 rDestinationHandle.Flags |= 0x10; 526 } 527 } 528 */ 529 else if ( rPropVal.Name.equals( sRefX ) ) 530 { 531 if ( rPropVal.Value >>= rDestinationHandle.nRefX ) 532 rDestinationHandle.nFlags |= HANDLE_FLAGS_REFX; 533 } 534 else if ( rPropVal.Name.equals( sRefY ) ) 535 { 536 if ( rPropVal.Value >>= rDestinationHandle.nRefY ) 537 rDestinationHandle.nFlags |= HANDLE_FLAGS_REFY; 538 } 539 else if ( rPropVal.Name.equals( sRefAngle ) ) 540 { 541 if ( rPropVal.Value >>= rDestinationHandle.nRefAngle ) 542 rDestinationHandle.nFlags |= HANDLE_FLAGS_REFANGLE; 543 } 544 else if ( rPropVal.Name.equals( sRefR ) ) 545 { 546 if ( rPropVal.Value >>= rDestinationHandle.nRefR ) 547 rDestinationHandle.nFlags |= HANDLE_FLAGS_REFR; 548 } 549 else if ( rPropVal.Name.equals( sRadiusRangeMinimum ) ) 550 { 551 if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMinimum ) 552 rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MINIMUM; 553 } 554 else if ( rPropVal.Name.equals( sRadiusRangeMaximum ) ) 555 { 556 if ( rPropVal.Value >>= rDestinationHandle.aRadiusRangeMaximum ) 557 rDestinationHandle.nFlags |= HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM; 558 } 559 else if ( rPropVal.Name.equals( sRangeXMinimum ) ) 560 { 561 if ( rPropVal.Value >>= rDestinationHandle.aXRangeMinimum ) 562 rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MINIMUM; 563 } 564 else if ( rPropVal.Name.equals( sRangeXMaximum ) ) 565 { 566 if ( rPropVal.Value >>= rDestinationHandle.aXRangeMaximum ) 567 rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_X_MAXIMUM; 568 } 569 else if ( rPropVal.Name.equals( sRangeYMinimum ) ) 570 { 571 if ( rPropVal.Value >>= rDestinationHandle.aYRangeMinimum ) 572 rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MINIMUM; 573 } 574 else if ( rPropVal.Name.equals( sRangeYMaximum ) ) 575 { 576 if ( rPropVal.Value >>= rDestinationHandle.aYRangeMaximum ) 577 rDestinationHandle.nFlags |= HANDLE_FLAGS_RANGE_Y_MAXIMUM; 578 } 579 } 580 } 581 return bRetValue; 582 } 583 584 const sal_Int32* EnhancedCustomShape2d::ApplyShapeAttributes( const SdrCustomShapeGeometryItem& rGeometryItem ) 585 { 586 const sal_Int32* pDefData = NULL; 587 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType ); 588 if ( pDefCustomShape ) 589 pDefData = pDefCustomShape->pDefData; 590 591 ////////////////////// 592 // AdjustmentValues // 593 ////////////////////// 594 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); 595 const Any* pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sAdjustmentValues ); 596 if ( pAny ) 597 *pAny >>= seqAdjustmentValues; 598 599 /////////////// 600 // Coordsize // 601 /////////////// 602 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) ); 603 const Any* pViewBox = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sViewBox ); 604 com::sun::star::awt::Rectangle aViewBox; 605 if ( pViewBox && (*pViewBox >>= aViewBox ) ) 606 { 607 nCoordLeft = aViewBox.X; 608 nCoordTop = aViewBox.Y; 609 nCoordWidth = labs( aViewBox.Width ); 610 nCoordHeight= labs( aViewBox.Height); 611 } 612 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); 613 614 ////////////////////// 615 // Path/Coordinates // 616 ////////////////////// 617 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) ); 618 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sCoordinates ); 619 if ( pAny ) 620 *pAny >>= seqCoordinates; 621 622 ///////////////////// 623 // Path/GluePoints // 624 ///////////////////// 625 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) ); 626 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sGluePoints ); 627 if ( pAny ) 628 *pAny >>= seqGluePoints; 629 630 /////////////////// 631 // Path/Segments // 632 /////////////////// 633 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) ); 634 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sSegments ); 635 if ( pAny ) 636 *pAny >>= seqSegments; 637 638 /////////////////// 639 // Path/StretchX // 640 /////////////////// 641 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) ); 642 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sStretchX ); 643 if ( pAny ) 644 { 645 sal_Int32 nStretchX = 0; 646 if ( *pAny >>= nStretchX ) 647 nXRef = nStretchX; 648 } 649 650 /////////////////// 651 // Path/StretchY // 652 /////////////////// 653 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) ); 654 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sStretchY ); 655 if ( pAny ) 656 { 657 sal_Int32 nStretchY = 0; 658 if ( *pAny >>= nStretchY ) 659 nYRef = nStretchY; 660 } 661 662 ///////////////////// 663 // Path/TextFrames // 664 ///////////////////// 665 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) ); 666 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sTextFrames ); 667 if ( pAny ) 668 *pAny >>= seqTextFrames; 669 670 /////////////// 671 // Equations // 672 /////////////// 673 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) ); 674 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sEquations ); 675 if ( pAny ) 676 *pAny >>= seqEquations; 677 678 ///////////// 679 // Handles // 680 ///////////// 681 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) ); 682 pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sHandles ); 683 if ( pAny ) 684 *pAny >>= seqHandles; 685 686 return pDefData; 687 } 688 689 EnhancedCustomShape2d::~EnhancedCustomShape2d() 690 { 691 } 692 693 EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) : 694 SfxItemSet ( pAObj->GetMergedItemSet() ), 695 pCustomShapeObj ( pAObj ), 696 eSpType ( mso_sptNil ), 697 nCoordLeft ( 0 ), 698 nCoordTop ( 0 ), 699 nCoordWidth ( 21600 ), 700 nCoordHeight ( 21600 ), 701 nXRef ( 0x80000000 ), 702 nYRef ( 0x80000000 ), 703 nFlags ( 0 ), 704 nColorData ( 0 ), 705 bTextFlow ( sal_False ), 706 bFilled ( ((const XFillStyleItem&)pAObj->GetMergedItem( XATTR_FILLSTYLE )).GetValue() != XFILL_NONE ), 707 bStroked ( ((const XLineStyleItem&)pAObj->GetMergedItem( XATTR_LINESTYLE )).GetValue() != XLINE_NONE ), 708 bFlipH ( sal_False ), 709 bFlipV ( sal_False ) 710 { 711 // bTextFlow needs to be set before clearing the TextDirection Item 712 713 ClearItem( SDRATTR_TEXTDIRECTION ); //SJ: vertical writing is not required, by removing this item no outliner is created 714 715 // #i105323# For 2D AtoShapes, the shadow attirbute does not need to be applied to any 716 // of the constucted helper SdrObjects. This would lead to problems since the shadow 717 // of one helper object would fall on one helper object behind it (e.g. with the 718 // eyes of the smiley shape). This is not wanted; instead a single shadow 'behind' 719 // the AutoShape visualisation is wanted. This is done with primitive functionailty 720 // now in SdrCustomShapePrimitive2D::create2DDecomposition, but only for 2D objects 721 // (see there and in EnhancedCustomShape3d::Create3DObject to read more). 722 // This exception may be removed later when AutoShapes will create primitives directly. 723 // So, currently remove the ShadowAttribute from the ItemSet to not apply it to any 724 // 2D helper shape. 725 ClearItem(SDRATTR_SHADOW); 726 727 Point aP( pCustomShapeObj->GetSnapRect().Center() ); 728 Size aS( pCustomShapeObj->GetLogicRect().GetSize() ); 729 aP.X() -= aS.Width() / 2; 730 aP.Y() -= aS.Height() / 2; 731 aLogicRect = Rectangle( aP, aS ); 732 733 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 734 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) ); 735 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) ); 736 737 rtl::OUString sShapeType; 738 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&)pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 739 Any* pAny = rGeometryItem.GetPropertyValueByName( sType ); 740 if ( pAny ) 741 *pAny >>= sShapeType; 742 eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType ); 743 744 pAny = rGeometryItem.GetPropertyValueByName( sMirroredX ); 745 if ( pAny ) 746 *pAny >>= bFlipH; 747 pAny = rGeometryItem.GetPropertyValueByName( sMirroredY ); 748 if ( pAny ) 749 *pAny >>= bFlipV; 750 751 if ( pCustomShapeObj->ISA( SdrObjCustomShape ) ) // should always be a SdrObjCustomShape, but you don't know 752 nRotateAngle = (sal_Int32)(((SdrObjCustomShape*)pCustomShapeObj)->GetObjectRotation() * 100.0); 753 else 754 nRotateAngle = pCustomShapeObj->GetRotateAngle(); 755 756 /*const sal_Int32* pDefData =*/ ApplyShapeAttributes( rGeometryItem ); 757 switch( eSpType ) 758 { 759 case mso_sptCan : nColorData = 0x20400000; break; 760 case mso_sptCube : nColorData = 0x302e0000; break; 761 case mso_sptActionButtonBlank : nColorData = 0x502ce400; break; 762 case mso_sptActionButtonHome : nColorData = 0x702ce4ce; break; 763 case mso_sptActionButtonHelp : nColorData = 0x602ce4c0; break; 764 case mso_sptActionButtonInformation : nColorData = 0x702ce4c5; break; 765 case mso_sptActionButtonBackPrevious : nColorData = 0x602ce4c0; break; 766 case mso_sptActionButtonForwardNext : nColorData = 0x602ce4c0; break; 767 case mso_sptActionButtonBeginning : nColorData = 0x602ce4c0; break; 768 case mso_sptActionButtonEnd : nColorData = 0x602ce4c0; break; 769 case mso_sptActionButtonReturn : nColorData = 0x602ce4c0; break; 770 case mso_sptActionButtonDocument : nColorData = 0x702ce4ec; break; 771 case mso_sptActionButtonSound : nColorData = 0x602ce4c0; break; 772 case mso_sptActionButtonMovie : nColorData = 0x602ce4c0; break; 773 case mso_sptBevel : nColorData = 0x502ce400; break; 774 case mso_sptFoldedCorner : nColorData = 0x20e00000; break; 775 case mso_sptSmileyFace : nColorData = 0x20e00000; break; 776 case mso_sptNil : 777 { 778 if( sShapeType.getLength() > 4 && 779 sShapeType.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "col-" ))) 780 { 781 nColorData = sShapeType.copy( 4 ).toInt32( 16 ); 782 } 783 } 784 break; 785 case mso_sptCurvedLeftArrow : 786 case mso_sptCurvedRightArrow : 787 case mso_sptCurvedUpArrow : 788 case mso_sptCurvedDownArrow : nColorData = 0x20d00000; break; 789 case mso_sptRibbon2 : nColorData = 0x30ee0000; break; 790 case mso_sptRibbon : nColorData = 0x30ee0000; break; 791 792 case mso_sptEllipseRibbon2 : nColorData = 0x30ee0000; break; 793 case mso_sptEllipseRibbon : nColorData = 0x30ee0000; break; 794 795 case mso_sptVerticalScroll : nColorData = 0x30ee0000; break; 796 case mso_sptHorizontalScroll : nColorData = 0x30ee0000; break; 797 default: 798 break; 799 } 800 fXScale = nCoordWidth == 0 ? 0.0 : (double)aLogicRect.GetWidth() / (double)nCoordWidth; 801 fYScale = nCoordHeight == 0 ? 0.0 : (double)aLogicRect.GetHeight() / (double)nCoordHeight; 802 if ( (sal_uInt32)nXRef != 0x80000000 && aLogicRect.GetHeight() ) 803 { 804 fXRatio = (double)aLogicRect.GetWidth() / (double)aLogicRect.GetHeight(); 805 if ( fXRatio > 1 ) 806 fXScale /= fXRatio; 807 else 808 fXRatio = 1.0; 809 } 810 else 811 fXRatio = 1.0; 812 if ( (sal_uInt32)nYRef != 0x80000000 && aLogicRect.GetWidth() ) 813 { 814 fYRatio = (double)aLogicRect.GetHeight() / (double)aLogicRect.GetWidth(); 815 if ( fYRatio > 1 ) 816 fYScale /= fYRatio; 817 else 818 fYRatio = 1.0; 819 } 820 else 821 fYRatio = 1.0; 822 823 sal_Int32 i, nLength = seqEquations.getLength(); 824 825 826 if ( nLength ) 827 { 828 vNodesSharedPtr.resize( nLength ); 829 for ( i = 0; i < seqEquations.getLength(); i++ ) 830 { 831 try 832 { 833 vNodesSharedPtr[ i ] = EnhancedCustomShape::FunctionParser::parseFunction( seqEquations[ i ], *this ); 834 } 835 catch ( EnhancedCustomShape::ParseError& ) 836 { 837 } 838 } 839 } 840 } 841 double EnhancedCustomShape2d::GetEnumFunc( const EnumFunc eFunc ) const 842 { 843 double fRet = 0.0; 844 switch( eFunc ) 845 { 846 case ENUM_FUNC_PI : fRet = F_PI; break; 847 case ENUM_FUNC_LEFT : fRet = 0.0; break; 848 case ENUM_FUNC_TOP : fRet = 0.0; break; 849 case ENUM_FUNC_RIGHT : fRet = (double)nCoordWidth * fXRatio; break; 850 case ENUM_FUNC_BOTTOM : fRet = (double)nCoordHeight * fYRatio; break; 851 case ENUM_FUNC_XSTRETCH : fRet = nXRef; break; 852 case ENUM_FUNC_YSTRETCH : fRet = nYRef; break; 853 case ENUM_FUNC_HASSTROKE : fRet = bStroked ? 1.0 : 0.0; break; 854 case ENUM_FUNC_HASFILL : fRet = bFilled ? 1.0 : 0.0; break; 855 case ENUM_FUNC_WIDTH : fRet = nCoordWidth; break; 856 case ENUM_FUNC_HEIGHT : fRet = nCoordHeight; break; 857 case ENUM_FUNC_LOGWIDTH : fRet = aLogicRect.GetWidth(); break; 858 case ENUM_FUNC_LOGHEIGHT : fRet = aLogicRect.GetHeight(); break; 859 } 860 return fRet; 861 } 862 double EnhancedCustomShape2d::GetAdjustValueAsDouble( const sal_Int32 nIndex ) const 863 { 864 double fNumber = 0.0; 865 if ( nIndex < seqAdjustmentValues.getLength() ) 866 { 867 if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE ) 868 seqAdjustmentValues[ nIndex ].Value >>= fNumber; 869 else 870 { 871 sal_Int32 nNumber = 0; 872 seqAdjustmentValues[ nIndex ].Value >>= nNumber; 873 fNumber = (double)nNumber; 874 } 875 } 876 return fNumber; 877 } 878 double EnhancedCustomShape2d::GetEquationValueAsDouble( const sal_Int32 nIndex ) const 879 { 880 double fNumber = 0.0; 881 if ( nIndex < (sal_Int32)vNodesSharedPtr.size() ) 882 { 883 if ( vNodesSharedPtr[ nIndex ].get() ) 884 try 885 { 886 fNumber = (*vNodesSharedPtr[ nIndex ])(); 887 if ( !rtl::math::isFinite( fNumber ) ) 888 fNumber = 0.0; 889 } 890 catch ( ... ) 891 { 892 /* sal_Bool bUps = sal_True; */ 893 } 894 } 895 return fNumber; 896 } 897 sal_Int32 EnhancedCustomShape2d::GetAdjustValueAsInteger( const sal_Int32 nIndex, const sal_Int32 nDefault ) const 898 { 899 sal_Int32 nNumber = nDefault; 900 if ( nIndex < seqAdjustmentValues.getLength() ) 901 { 902 if ( seqAdjustmentValues[ nIndex ].Value.getValueTypeClass() == TypeClass_DOUBLE ) 903 { 904 double fNumber = 0; 905 seqAdjustmentValues[ nIndex ].Value >>= fNumber; 906 nNumber = (sal_Int32)fNumber; 907 } 908 else 909 seqAdjustmentValues[ nIndex ].Value >>= nNumber; 910 } 911 return nNumber; 912 } 913 sal_Bool EnhancedCustomShape2d::SetAdjustValueAsDouble( const double& rValue, const sal_Int32 nIndex ) 914 { 915 sal_Bool bRetValue = sal_False; 916 if ( nIndex < seqAdjustmentValues.getLength() ) 917 { 918 // updating our local adjustment sequence 919 seqAdjustmentValues[ nIndex ].Value <<= rValue; 920 seqAdjustmentValues[ nIndex ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; 921 bRetValue = sal_True; 922 } 923 return bRetValue; 924 } 925 926 Point EnhancedCustomShape2d::GetPoint( const com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPair, 927 const sal_Bool bScale, const sal_Bool bReplaceGeoSize ) const 928 { 929 Point aRetValue; 930 sal_Bool bExchange = ( nFlags & DFF_CUSTOMSHAPE_EXCH ) != 0; // x <-> y 931 sal_uInt32 nPass = 0; 932 do 933 { 934 sal_uInt32 nIndex = nPass; 935 936 if ( bExchange ) 937 nIndex ^= 1; 938 939 double fVal; 940 const EnhancedCustomShapeParameter& rParameter = nIndex ? rPair.Second : rPair.First; 941 if ( nPass ) // height 942 { 943 GetParameter( fVal, rParameter, sal_False, bReplaceGeoSize ); 944 fVal -= nCoordTop; 945 if ( bScale ) 946 { 947 fVal *= fYScale; 948 949 if ( nFlags & DFF_CUSTOMSHAPE_FLIP_V ) 950 fVal = aLogicRect.GetHeight() - fVal; 951 } 952 aRetValue.Y() = (sal_Int32)fVal; 953 } 954 else // width 955 { 956 GetParameter( fVal, rParameter, bReplaceGeoSize, sal_False ); 957 fVal -= nCoordLeft; 958 if ( bScale ) 959 { 960 fVal *= fXScale; 961 962 if ( nFlags & DFF_CUSTOMSHAPE_FLIP_H ) 963 fVal = aLogicRect.GetWidth() - fVal; 964 } 965 aRetValue.X() = (sal_Int32)fVal; 966 } 967 } 968 while ( ++nPass < 2 ); 969 return aRetValue; 970 } 971 972 sal_Bool EnhancedCustomShape2d::GetParameter( double& rRetValue, const EnhancedCustomShapeParameter& rParameter, 973 const sal_Bool bReplaceGeoWidth, const sal_Bool bReplaceGeoHeight ) const 974 { 975 rRetValue = 0.0; 976 sal_Bool bRetValue = sal_False; 977 switch ( rParameter.Type ) 978 { 979 case EnhancedCustomShapeParameterType::ADJUSTMENT : 980 { 981 sal_Int32 nAdjustmentIndex = 0; 982 if ( rParameter.Value >>= nAdjustmentIndex ) 983 { 984 rRetValue = GetAdjustValueAsDouble( nAdjustmentIndex ); 985 bRetValue = sal_True; 986 } 987 } 988 break; 989 case EnhancedCustomShapeParameterType::EQUATION : 990 { 991 sal_Int32 nEquationIndex = 0; 992 if ( rParameter.Value >>= nEquationIndex ) 993 { 994 rRetValue = GetEquationValueAsDouble( nEquationIndex ); 995 bRetValue = sal_True; 996 } 997 } 998 break; 999 case EnhancedCustomShapeParameterType::NORMAL : 1000 { 1001 if ( rParameter.Value.getValueTypeClass() == TypeClass_DOUBLE ) 1002 { 1003 double fValue; 1004 if ( rParameter.Value >>= fValue ) 1005 { 1006 rRetValue = fValue; 1007 bRetValue = sal_True; 1008 } 1009 } 1010 else 1011 { 1012 sal_Int32 nValue = 0; 1013 if ( rParameter.Value >>= nValue ) 1014 { 1015 rRetValue = nValue; 1016 bRetValue = sal_True; 1017 if ( bReplaceGeoWidth && ( nValue == nCoordWidth ) ) 1018 rRetValue *= fXRatio; 1019 else if ( bReplaceGeoHeight && ( nValue == nCoordHeight ) ) 1020 rRetValue *= fYRatio; 1021 } 1022 } 1023 } 1024 break; 1025 case EnhancedCustomShapeParameterType::LEFT : 1026 { 1027 rRetValue = 0.0; 1028 bRetValue = sal_True; 1029 } 1030 break; 1031 case EnhancedCustomShapeParameterType::TOP : 1032 { 1033 rRetValue = 0.0; 1034 bRetValue = sal_True; 1035 } 1036 break; 1037 case EnhancedCustomShapeParameterType::RIGHT : 1038 { 1039 rRetValue = nCoordWidth; 1040 bRetValue = sal_True; 1041 } 1042 break; 1043 case EnhancedCustomShapeParameterType::BOTTOM : 1044 { 1045 rRetValue = nCoordHeight; 1046 bRetValue = sal_True; 1047 } 1048 break; 1049 } 1050 return bRetValue; 1051 } 1052 1053 // nLumDat 28-31 = number of luminance entries in nLumDat 1054 // nLumDat 27-24 = nLumDatEntry 0 1055 // nLumDat 23-20 = nLumDatEntry 1 ... 1056 // each 4bit entry is to be interpreted as a 10 percent signed luminance changing 1057 sal_Int32 EnhancedCustomShape2d::GetLuminanceChange( sal_uInt32 nIndex ) const 1058 { 1059 const sal_uInt32 nCount = nColorData >> 28; 1060 if ( !nCount ) 1061 return 0; 1062 1063 if ( nIndex >= nCount ) 1064 nIndex = nCount - 1; 1065 1066 const sal_Int32 nLumDat = nColorData << ( ( 1 + nIndex ) << 2 ); 1067 return ( nLumDat >> 28 ) * 10; 1068 } 1069 1070 Color EnhancedCustomShape2d::GetColorData( const Color& rFillColor, sal_uInt32 nIndex ) const 1071 { 1072 const sal_Int32 nLuminance = GetLuminanceChange(nIndex); 1073 if( !nLuminance ) 1074 return rFillColor; 1075 1076 basegfx::BColor aHSVColor= 1077 basegfx::tools::rgb2hsv( 1078 basegfx::BColor(rFillColor.GetRed()/255.0, 1079 rFillColor.GetGreen()/255.0, 1080 rFillColor.GetBlue()/255.0)); 1081 if( nLuminance > 0 ) 1082 { 1083 aHSVColor.setGreen( 1084 aHSVColor.getGreen() * (1.0-nLuminance/100.0)); 1085 aHSVColor.setBlue( 1086 nLuminance/100.0 + 1087 (1.0-nLuminance/100.0)*aHSVColor.getBlue()); 1088 } 1089 else if( nLuminance < 0 ) 1090 { 1091 aHSVColor.setBlue( 1092 (1.0+nLuminance/100.0)*aHSVColor.getBlue()); 1093 } 1094 1095 aHSVColor = basegfx::tools::hsv2rgb(aHSVColor); 1096 return Color( (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(aHSVColor.getRed(),0.0,1.0) * 255.0 + 0.5 ), 1097 (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(aHSVColor.getGreen(),0.0,1.0) * 255.0 + 0.5 ), 1098 (sal_uInt8)static_cast< sal_Int32 >( basegfx::clamp(aHSVColor.getBlue(),0.0,1.0) * 255.0 + 0.5 ) ); 1099 } 1100 1101 Rectangle EnhancedCustomShape2d::GetTextRect() const 1102 { 1103 sal_Int32 nIndex, nSize = seqTextFrames.getLength(); 1104 if ( !nSize ) 1105 return aLogicRect; 1106 nIndex = 0; 1107 if ( bTextFlow && ( nSize > 1 ) ) 1108 nIndex++; 1109 Point aTopLeft( GetPoint( seqTextFrames[ nIndex ].TopLeft, sal_True, sal_True ) ); 1110 Point aBottomRight( GetPoint( seqTextFrames[ nIndex ].BottomRight, sal_True, sal_True ) ); 1111 if ( bFlipH ) 1112 { 1113 aTopLeft.X() = aLogicRect.GetWidth() - aTopLeft.X(); 1114 aBottomRight.X() = aLogicRect.GetWidth() - aBottomRight.X(); 1115 } 1116 if ( bFlipV ) 1117 { 1118 aTopLeft.Y() = aLogicRect.GetHeight() - aTopLeft.Y(); 1119 aBottomRight.Y() = aLogicRect.GetHeight() - aBottomRight.Y(); 1120 } 1121 Rectangle aRect( aTopLeft, aBottomRight ); 1122 aRect.Move( aLogicRect.Left(), aLogicRect.Top() ); 1123 aRect.Justify(); 1124 return aRect; 1125 } 1126 1127 sal_uInt32 EnhancedCustomShape2d::GetHdlCount() const 1128 { 1129 return seqHandles.getLength(); 1130 } 1131 1132 sal_Bool EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex, Point& rReturnPosition ) const 1133 { 1134 sal_Bool bRetValue = sal_False; 1135 if ( nIndex < GetHdlCount() ) 1136 { 1137 Handle aHandle; 1138 if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) ) 1139 { 1140 if ( aHandle.nFlags & HANDLE_FLAGS_POLAR ) 1141 { 1142 Point aReferencePoint( GetPoint( aHandle.aPolar, sal_True, sal_False ) ); 1143 1144 double fAngle; 1145 double fRadius; 1146 GetParameter( fRadius, aHandle.aPosition.First, sal_False, sal_False ); 1147 GetParameter( fAngle, aHandle.aPosition.Second, sal_False, sal_False ); 1148 1149 double a = ( 360.0 - fAngle ) * F_PI180; 1150 double dx = fRadius * fXScale; 1151 double fX = dx * cos( a ); 1152 double fY =-dx * sin( a ); 1153 rReturnPosition = 1154 Point( 1155 Round( fX + aReferencePoint.X() ), 1156 basegfx::fTools::equalZero(fXScale) ? aReferencePoint.Y() : 1157 Round( ( fY * fYScale ) / fXScale + aReferencePoint.Y() ) ); 1158 } 1159 else 1160 { 1161 if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED ) 1162 { 1163 if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() ) 1164 { 1165 com::sun::star::drawing::EnhancedCustomShapeParameter aFirst = aHandle.aPosition.First; 1166 com::sun::star::drawing::EnhancedCustomShapeParameter aSecond = aHandle.aPosition.Second; 1167 aHandle.aPosition.First = aSecond; 1168 aHandle.aPosition.Second = aFirst; 1169 } 1170 } 1171 rReturnPosition = GetPoint( aHandle.aPosition, sal_True, sal_False ); 1172 } 1173 const GeoStat aGeoStat( ((SdrObjCustomShape*)pCustomShapeObj)->GetGeoStat() ); 1174 if ( aGeoStat.nShearWink ) 1175 { 1176 double nTan = aGeoStat.nTan; 1177 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) 1178 nTan = -nTan; 1179 ShearPoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan ); 1180 } 1181 if ( nRotateAngle ) 1182 { 1183 double a = nRotateAngle * F_PI18000; 1184 RotatePoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) ); 1185 } 1186 if ( bFlipH ) 1187 rReturnPosition.X() = aLogicRect.GetWidth() - rReturnPosition.X(); 1188 if ( bFlipV ) 1189 rReturnPosition.Y() = aLogicRect.GetHeight() - rReturnPosition.Y(); 1190 rReturnPosition.Move( aLogicRect.Left(), aLogicRect.Top() ); 1191 bRetValue = sal_True; 1192 } 1193 } 1194 return bRetValue; 1195 } 1196 1197 sal_Bool EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nIndex, const com::sun::star::awt::Point& rPosition ) 1198 { 1199 sal_Bool bRetValue = sal_False; 1200 if ( nIndex < GetHdlCount() ) 1201 { 1202 Handle aHandle; 1203 if ( ConvertSequenceToEnhancedCustomShape2dHandle( seqHandles[ nIndex ], aHandle ) ) 1204 { 1205 Point aP( rPosition.X, rPosition.Y ); 1206 // apply the negative object rotation to the controller position 1207 1208 aP.Move( -aLogicRect.Left(), -aLogicRect.Top() ); 1209 if ( bFlipH ) 1210 aP.X() = aLogicRect.GetWidth() - aP.X(); 1211 if ( bFlipV ) 1212 aP.Y() = aLogicRect.GetHeight() - aP.Y(); 1213 if ( nRotateAngle ) 1214 { 1215 double a = -nRotateAngle * F_PI18000; 1216 RotatePoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) ); 1217 } 1218 const GeoStat aGeoStat( ((SdrObjCustomShape*)pCustomShapeObj)->GetGeoStat() ); 1219 if ( aGeoStat.nShearWink ) 1220 { 1221 double nTan = -aGeoStat.nTan; 1222 if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) 1223 nTan = -nTan; 1224 ShearPoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan ); 1225 } 1226 1227 double fPos1 = aP.X(); //( bFlipH ) ? aLogicRect.GetWidth() - aP.X() : aP.X(); 1228 double fPos2 = aP.Y(); //( bFlipV ) ? aLogicRect.GetHeight() -aP.Y() : aP.Y(); 1229 fPos1 /= fXScale; 1230 fPos2 /= fYScale; 1231 1232 if ( aHandle.nFlags & HANDLE_FLAGS_SWITCHED ) 1233 { 1234 if ( aLogicRect.GetHeight() > aLogicRect.GetWidth() ) 1235 { 1236 double fX = fPos1; 1237 double fY = fPos2; 1238 fPos1 = fY; 1239 fPos2 = fX; 1240 } 1241 } 1242 1243 sal_Int32 nFirstAdjustmentValue = -1, nSecondAdjustmentValue = -1; 1244 1245 if ( aHandle.aPosition.First.Type == EnhancedCustomShapeParameterType::ADJUSTMENT ) 1246 aHandle.aPosition.First.Value >>= nFirstAdjustmentValue; 1247 if ( aHandle.aPosition.Second.Type == EnhancedCustomShapeParameterType::ADJUSTMENT ) 1248 aHandle.aPosition.Second.Value>>= nSecondAdjustmentValue; 1249 1250 if ( aHandle.nFlags & HANDLE_FLAGS_POLAR ) 1251 { 1252 double fXRef, fYRef, fAngle; 1253 GetParameter( fXRef, aHandle.aPolar.First, sal_False, sal_False ); 1254 GetParameter( fYRef, aHandle.aPolar.Second, sal_False, sal_False ); 1255 const double fDX = fPos1 - fXRef; 1256 fAngle = -( atan2( -fPos2 + fYRef, ( ( fDX == 0.0L ) ? 0.000000001 : fDX ) ) / F_PI180 ); 1257 double fX = ( fPos1 - fXRef ); 1258 double fY = ( fPos2 - fYRef ); 1259 double fRadius = sqrt( fX * fX + fY * fY ); 1260 if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MINIMUM ) 1261 { 1262 double fMin; 1263 GetParameter( fMin, aHandle.aRadiusRangeMinimum, sal_False, sal_False ); 1264 if ( fRadius < fMin ) 1265 fRadius = fMin; 1266 } 1267 if ( aHandle.nFlags & HANDLE_FLAGS_RADIUS_RANGE_MAXIMUM ) 1268 { 1269 double fMax; 1270 GetParameter( fMax, aHandle.aRadiusRangeMaximum, sal_False, sal_False ); 1271 if ( fRadius > fMax ) 1272 fRadius = fMax; 1273 } 1274 if ( nFirstAdjustmentValue >= 0 ) 1275 SetAdjustValueAsDouble( fRadius, nFirstAdjustmentValue ); 1276 if ( nSecondAdjustmentValue >= 0 ) 1277 SetAdjustValueAsDouble( fAngle, nSecondAdjustmentValue ); 1278 } 1279 else 1280 { 1281 if ( aHandle.nFlags & HANDLE_FLAGS_REFX ) 1282 { 1283 nFirstAdjustmentValue = aHandle.nRefX; 1284 fPos1 *= 100000.0; 1285 fPos1 /= nCoordWidth; 1286 } 1287 if ( aHandle.nFlags & HANDLE_FLAGS_REFY ) 1288 { 1289 nSecondAdjustmentValue = aHandle.nRefY; 1290 fPos2 *= 100000.0; 1291 fPos2 /= nCoordHeight; 1292 } 1293 if ( nFirstAdjustmentValue >= 0 ) 1294 { 1295 if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MINIMUM ) // check if horizontal handle needs to be within a range 1296 { 1297 double fXMin; 1298 GetParameter( fXMin, aHandle.aXRangeMinimum, sal_False, sal_False ); 1299 if ( fPos1 < fXMin ) 1300 fPos1 = fXMin; 1301 } 1302 if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_X_MAXIMUM ) // check if horizontal handle needs to be within a range 1303 { 1304 double fXMax; 1305 GetParameter( fXMax, aHandle.aXRangeMaximum, sal_False, sal_False ); 1306 if ( fPos1 > fXMax ) 1307 fPos1 = fXMax; 1308 } 1309 SetAdjustValueAsDouble( fPos1, nFirstAdjustmentValue ); 1310 } 1311 if ( nSecondAdjustmentValue >= 0 ) 1312 { 1313 if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MINIMUM ) // check if vertical handle needs to be within a range 1314 { 1315 double fYMin; 1316 GetParameter( fYMin, aHandle.aYRangeMinimum, sal_False, sal_False ); 1317 if ( fPos2 < fYMin ) 1318 fPos2 = fYMin; 1319 } 1320 if ( aHandle.nFlags & HANDLE_FLAGS_RANGE_Y_MAXIMUM ) // check if vertical handle needs to be within a range 1321 { 1322 double fYMax; 1323 GetParameter( fYMax, aHandle.aYRangeMaximum, sal_False, sal_False ); 1324 if ( fPos2 > fYMax ) 1325 fPos2 = fYMax; 1326 } 1327 SetAdjustValueAsDouble( fPos2, nSecondAdjustmentValue ); 1328 } 1329 } 1330 // and writing them back into the GeometryItem 1331 SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&) 1332 (const SdrCustomShapeGeometryItem&)pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY )); 1333 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); 1334 com::sun::star::beans::PropertyValue aPropVal; 1335 aPropVal.Name = sAdjustmentValues; 1336 aPropVal.Value <<= seqAdjustmentValues; 1337 aGeometryItem.SetPropertyValue( aPropVal ); 1338 pCustomShapeObj->SetMergedItem( aGeometryItem ); 1339 bRetValue = sal_True; 1340 } 1341 } 1342 return bRetValue; 1343 } 1344 1345 void EnhancedCustomShape2d::SwapStartAndEndArrow( SdrObject* pObj ) //#108274 1346 { 1347 XLineStartItem aLineStart; 1348 aLineStart.SetLineStartValue(((XLineStartItem&)pObj->GetMergedItem( XATTR_LINEEND )).GetLineStartValue()); 1349 XLineStartWidthItem aLineStartWidth(((XLineStartWidthItem&)pObj->GetMergedItem( XATTR_LINEENDWIDTH )).GetValue()); 1350 XLineStartCenterItem aLineStartCenter(((XLineStartCenterItem&)pObj->GetMergedItem( XATTR_LINEENDCENTER )).GetValue()); 1351 1352 XLineEndItem aLineEnd; 1353 aLineEnd.SetLineEndValue(((XLineEndItem&)pObj->GetMergedItem( XATTR_LINESTART )).GetLineEndValue()); 1354 XLineEndWidthItem aLineEndWidth(((XLineEndWidthItem&)pObj->GetMergedItem( XATTR_LINESTARTWIDTH )).GetValue()); 1355 XLineEndCenterItem aLineEndCenter(((XLineEndCenterItem&)pObj->GetMergedItem( XATTR_LINESTARTCENTER )).GetValue()); 1356 1357 pObj->SetMergedItem( aLineStart ); 1358 pObj->SetMergedItem( aLineStartWidth ); 1359 pObj->SetMergedItem( aLineStartCenter ); 1360 pObj->SetMergedItem( aLineEnd ); 1361 pObj->SetMergedItem( aLineEndWidth ); 1362 pObj->SetMergedItem( aLineEndCenter ); 1363 } 1364 1365 basegfx::B2DPolygon CreateArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, const sal_Bool bClockwise ) 1366 { 1367 Rectangle aRect( rRect ); 1368 Point aStart( rStart ); 1369 Point aEnd( rEnd ); 1370 1371 sal_Int32 bSwapStartEndAngle = 0; 1372 1373 if ( aRect.Left() > aRect.Right() ) 1374 bSwapStartEndAngle ^= 0x01; 1375 if ( aRect.Top() > aRect.Bottom() ) 1376 bSwapStartEndAngle ^= 0x11; 1377 if ( bSwapStartEndAngle ) 1378 { 1379 aRect.Justify(); 1380 if ( bSwapStartEndAngle & 1 ) 1381 { 1382 Point aTmp( aStart ); 1383 aStart = aEnd; 1384 aEnd = aTmp; 1385 } 1386 } 1387 1388 Polygon aTempPoly( aRect, aStart, aEnd, POLY_ARC ); 1389 basegfx::B2DPolygon aRetval; 1390 1391 if ( bClockwise ) 1392 { 1393 for ( sal_uInt16 j = aTempPoly.GetSize(); j--; ) 1394 { 1395 aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y())); 1396 } 1397 } 1398 else 1399 { 1400 for ( sal_uInt16 j = 0; j < aTempPoly.GetSize(); j++ ) 1401 { 1402 aRetval.append(basegfx::B2DPoint(aTempPoly[ j ].X(), aTempPoly[ j ].Y())); 1403 } 1404 } 1405 1406 return aRetval; 1407 } 1408 1409 void EnhancedCustomShape2d::CreateSubPath( sal_uInt16& rSrcPt, sal_uInt16& rSegmentInd, std::vector< SdrPathObj* >& rObjectList, 1410 const sal_Bool bLineGeometryNeededOnly, 1411 const sal_Bool bSortFilledObjectsToBack ) 1412 { 1413 sal_Bool bNoFill = sal_False; 1414 sal_Bool bNoStroke = sal_False; 1415 1416 basegfx::B2DPolyPolygon aNewB2DPolyPolygon; 1417 basegfx::B2DPolygon aNewB2DPolygon; 1418 1419 sal_Int32 nCoordSize = seqCoordinates.getLength(); 1420 sal_Int32 nSegInfoSize = seqSegments.getLength(); 1421 if ( !nSegInfoSize ) 1422 { 1423 const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray(); 1424 1425 for ( sal_Int32 nPtNum(0L); nPtNum < nCoordSize; nPtNum++ ) 1426 { 1427 const Point aTempPoint(GetPoint( *pTmp++, sal_True, sal_True )); 1428 aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y())); 1429 } 1430 1431 aNewB2DPolygon.setClosed(true); 1432 } 1433 else 1434 { 1435 for ( ;rSegmentInd < nSegInfoSize; ) 1436 { 1437 sal_Int16 nCommand = seqSegments[ rSegmentInd ].Command; 1438 sal_Int16 nPntCount= seqSegments[ rSegmentInd++ ].Count; 1439 1440 switch ( nCommand ) 1441 { 1442 case NOFILL : 1443 bNoFill = sal_True; 1444 break; 1445 case NOSTROKE : 1446 bNoStroke = sal_True; 1447 break; 1448 case MOVETO : 1449 { 1450 if(aNewB2DPolygon.count() > 1L) 1451 { 1452 // #i76201# Add conversion to closed polygon when first and last points are equal 1453 basegfx::tools::checkClosed(aNewB2DPolygon); 1454 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1455 } 1456 1457 aNewB2DPolygon.clear(); 1458 1459 if ( rSrcPt < nCoordSize ) 1460 { 1461 const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True )); 1462 aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y())); 1463 } 1464 } 1465 break; 1466 case ENDSUBPATH : 1467 break; 1468 case CLOSESUBPATH : 1469 { 1470 if(aNewB2DPolygon.count()) 1471 { 1472 if(aNewB2DPolygon.count() > 1L) 1473 { 1474 aNewB2DPolygon.setClosed(true); 1475 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1476 } 1477 1478 aNewB2DPolygon.clear(); 1479 } 1480 } 1481 break; 1482 case CURVETO : 1483 { 1484 for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ ) 1485 { 1486 const Point aControlA(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True )); 1487 const Point aControlB(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True )); 1488 const Point aEnd(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True )); 1489 1490 DBG_ASSERT(aNewB2DPolygon.count(), "EnhancedCustomShape2d::CreateSubPath: Error in adding control point (!)"); 1491 aNewB2DPolygon.appendBezierSegment( 1492 basegfx::B2DPoint(aControlA.X(), aControlA.Y()), 1493 basegfx::B2DPoint(aControlB.X(), aControlB.Y()), 1494 basegfx::B2DPoint(aEnd.X(), aEnd.Y())); 1495 } 1496 } 1497 break; 1498 1499 case ANGLEELLIPSE : 1500 { 1501 if(aNewB2DPolygon.count() > 1L) 1502 { 1503 // #i76201# Add conversion to closed polygon when first and last points are equal 1504 basegfx::tools::checkClosed(aNewB2DPolygon); 1505 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1506 } 1507 1508 aNewB2DPolygon.clear(); 1509 } 1510 case ANGLEELLIPSETO : 1511 { 1512 for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ ) 1513 { 1514 // create a circle 1515 Point _aCenter( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ) ); 1516 double fWidth, fHeight; 1517 GetParameter( fWidth, seqCoordinates[ rSrcPt + 1 ].First, sal_True, sal_False ); 1518 GetParameter( fHeight, seqCoordinates[ rSrcPt + 1 ].Second, sal_False, sal_True ); 1519 fWidth *= fXScale; 1520 fHeight*= fYScale; 1521 Point aP( (sal_Int32)( _aCenter.X() - fWidth ), (sal_Int32)( _aCenter.Y() - fHeight ) ); 1522 Size aS( (sal_Int32)( fWidth * 2.0 ), (sal_Int32)( fHeight * 2.0 ) ); 1523 Rectangle aRect( aP, aS ); 1524 if ( aRect.GetWidth() && aRect.GetHeight() ) 1525 { 1526 double fStartAngle, fEndAngle; 1527 GetParameter( fStartAngle, seqCoordinates[ rSrcPt + 2 ].First, sal_False, sal_False ); 1528 GetParameter( fEndAngle , seqCoordinates[ rSrcPt + 2 ].Second, sal_False, sal_False ); 1529 1530 if ( ((sal_Int32)fStartAngle % 360) != ((sal_Int32)fEndAngle % 360) ) 1531 { 1532 if ( (sal_Int32)fStartAngle & 0x7fff0000 ) // SJ: if the angle was imported from our escher import, then the 1533 fStartAngle /= 65536.0; // value is shifted by 16. TODO: already change the fixed float to a 1534 if ( (sal_Int32)fEndAngle & 0x7fff0000 ) // double in the import filter 1535 { 1536 fEndAngle /= 65536.0; 1537 fEndAngle = fEndAngle + fStartAngle; 1538 if ( fEndAngle < 0 ) 1539 { // in the binary filter the endangle is the amount 1540 double fTemp = fStartAngle; 1541 fStartAngle = fEndAngle; 1542 fEndAngle = fTemp; 1543 } 1544 } 1545 double fCenterX = aRect.Center().X(); 1546 double fCenterY = aRect.Center().Y(); 1547 double fx1 = ( cos( fStartAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX; 1548 double fy1 = ( -sin( fStartAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY; 1549 double fx2 = ( cos( fEndAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX; 1550 double fy2 = ( -sin( fEndAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY; 1551 aNewB2DPolygon.append(CreateArc( aRect, Point( (sal_Int32)fx1, (sal_Int32)fy1 ), Point( (sal_Int32)fx2, (sal_Int32)fy2 ), sal_False)); 1552 } 1553 else 1554 { /* SJ: TODO: this block should be replaced sometimes, because the current point 1555 is not set correct, it also does not use the correct moveto 1556 point if ANGLEELLIPSETO was used, but the method CreateArc 1557 is at the moment not able to draw full circles (if startangle is 0 1558 and endangle 360 nothing is painted :-( */ 1559 sal_Int32 nXControl = (sal_Int32)((double)aRect.GetWidth() * 0.2835 ); 1560 sal_Int32 nYControl = (sal_Int32)((double)aRect.GetHeight() * 0.2835 ); 1561 Point aCenter( aRect.Center() ); 1562 1563 // append start point 1564 aNewB2DPolygon.append(basegfx::B2DPoint(aCenter.X(), aRect.Top())); 1565 1566 // append four bezier segments 1567 aNewB2DPolygon.appendBezierSegment( 1568 basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Top()), 1569 basegfx::B2DPoint(aRect.Right(), aCenter.Y() - nYControl), 1570 basegfx::B2DPoint(aRect.Right(), aCenter.Y())); 1571 1572 aNewB2DPolygon.appendBezierSegment( 1573 basegfx::B2DPoint(aRect.Right(), aCenter.Y() + nYControl), 1574 basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Bottom()), 1575 basegfx::B2DPoint(aCenter.X(), aRect.Bottom())); 1576 1577 aNewB2DPolygon.appendBezierSegment( 1578 basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Bottom()), 1579 basegfx::B2DPoint(aRect.Left(), aCenter.Y() + nYControl), 1580 basegfx::B2DPoint(aRect.Left(), aCenter.Y())); 1581 1582 aNewB2DPolygon.appendBezierSegment( 1583 basegfx::B2DPoint(aRect.Left(), aCenter.Y() - nYControl), 1584 basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Top()), 1585 basegfx::B2DPoint(aCenter.X(), aRect.Top())); 1586 1587 // close, rescue last controlpoint, remove double last point 1588 basegfx::tools::closeWithGeometryChange(aNewB2DPolygon); 1589 } 1590 } 1591 rSrcPt += 3; 1592 } 1593 } 1594 break; 1595 1596 case LINETO : 1597 { 1598 for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ ) 1599 { 1600 const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True )); 1601 aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y())); 1602 } 1603 } 1604 break; 1605 1606 case ARC : 1607 case CLOCKWISEARC : 1608 { 1609 if(aNewB2DPolygon.count() > 1L) 1610 { 1611 // #i76201# Add conversion to closed polygon when first and last points are equal 1612 basegfx::tools::checkClosed(aNewB2DPolygon); 1613 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1614 } 1615 1616 aNewB2DPolygon.clear(); 1617 } 1618 case ARCTO : 1619 case CLOCKWISEARCTO : 1620 { 1621 sal_Bool bClockwise = ( nCommand == CLOCKWISEARC ) || ( nCommand == CLOCKWISEARCTO ); 1622 sal_uInt32 nXor = bClockwise ? 3 : 2; 1623 for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 3 ) < nCoordSize ); i++ ) 1624 { 1625 Rectangle aRect( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ), GetPoint( seqCoordinates[ rSrcPt + 1 ], sal_True, sal_True ) ); 1626 if ( aRect.GetWidth() && aRect.GetHeight() ) 1627 { 1628 Point aCenter( aRect.Center() ); 1629 Point aStart( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + nXor ) ], sal_True, sal_True ) ); 1630 Point aEnd( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + ( nXor ^ 1 ) ) ], sal_True, sal_True ) ); 1631 double fRatio = (double)aRect.GetHeight() / (double)aRect.GetWidth(); 1632 aStart.X() = (sal_Int32)( ( (double)( aStart.X() - aCenter.X() ) ) * fRatio ) + aCenter.X(); 1633 aStart.Y() = (sal_Int32)( ( (double)( aStart.Y() - aCenter.Y() ) ) ) + aCenter.Y(); 1634 aEnd.X() = (sal_Int32)( ( (double)( aEnd.X() - aCenter.X() ) ) * fRatio ) + aCenter.X(); 1635 aEnd.Y() = (sal_Int32)( ( (double)( aEnd.Y() - aCenter.Y() ) ) ) + aCenter.Y(); 1636 aNewB2DPolygon.append(CreateArc( aRect, aStart, aEnd, bClockwise)); 1637 } 1638 rSrcPt += 4; 1639 } 1640 } 1641 break; 1642 1643 case ELLIPTICALQUADRANTX : 1644 case ELLIPTICALQUADRANTY : 1645 { 1646 bool bFirstDirection(true); 1647 basegfx::B2DPoint aControlPointA; 1648 basegfx::B2DPoint aControlPointB; 1649 1650 for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ ) 1651 { 1652 sal_uInt32 nModT = ( nCommand == ELLIPTICALQUADRANTX ) ? 1 : 0; 1653 Point aCurrent( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ) ); 1654 1655 if ( rSrcPt ) // we need a previous point 1656 { 1657 Point aPrev( GetPoint( seqCoordinates[ rSrcPt - 1 ], sal_True, sal_True ) ); 1658 sal_Int32 nX, nY; 1659 nX = aCurrent.X() - aPrev.X(); 1660 nY = aCurrent.Y() - aPrev.Y(); 1661 if ( ( nY ^ nX ) & 0x80000000 ) 1662 { 1663 if ( !i ) 1664 bFirstDirection = true; 1665 else if ( !bFirstDirection ) 1666 nModT ^= 1; 1667 } 1668 else 1669 { 1670 if ( !i ) 1671 bFirstDirection = false; 1672 else if ( bFirstDirection ) 1673 nModT ^= 1; 1674 } 1675 if ( nModT ) // get the right corner 1676 { 1677 nX = aCurrent.X(); 1678 nY = aPrev.Y(); 1679 } 1680 else 1681 { 1682 nX = aPrev.X(); 1683 nY = aCurrent.Y(); 1684 } 1685 sal_Int32 nXVec = ( nX - aPrev.X() ) >> 1; 1686 sal_Int32 nYVec = ( nY - aPrev.Y() ) >> 1; 1687 Point aControl1( aPrev.X() + nXVec, aPrev.Y() + nYVec ); 1688 1689 aControlPointA = basegfx::B2DPoint(aControl1.X(), aControl1.Y()); 1690 1691 nXVec = ( nX - aCurrent.X() ) >> 1; 1692 nYVec = ( nY - aCurrent.Y() ) >> 1; 1693 Point aControl2( aCurrent.X() + nXVec, aCurrent.Y() + nYVec ); 1694 1695 aControlPointB = basegfx::B2DPoint(aControl2.X(), aControl2.Y()); 1696 1697 aNewB2DPolygon.appendBezierSegment( 1698 aControlPointA, 1699 aControlPointB, 1700 basegfx::B2DPoint(aCurrent.X(), aCurrent.Y())); 1701 } 1702 else 1703 { 1704 aNewB2DPolygon.append(basegfx::B2DPoint(aCurrent.X(), aCurrent.Y())); 1705 } 1706 1707 rSrcPt++; 1708 } 1709 } 1710 break; 1711 1712 #ifdef DBG_CUSTOMSHAPE 1713 case UNKNOWN : 1714 default : 1715 { 1716 ByteString aString( "CustomShapes::unknown PolyFlagValue :" ); 1717 aString.Append( ByteString::CreateFromInt32( nCommand ) ); 1718 DBG_ERROR( aString.GetBuffer() ); 1719 } 1720 break; 1721 #endif 1722 } 1723 if ( nCommand == ENDSUBPATH ) 1724 break; 1725 } 1726 } 1727 if ( rSegmentInd == nSegInfoSize ) 1728 rSegmentInd++; 1729 1730 if(aNewB2DPolygon.count() > 1L) 1731 { 1732 // #i76201# Add conversion to closed polygon when first and last points are equal 1733 basegfx::tools::checkClosed(aNewB2DPolygon); 1734 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1735 } 1736 1737 if(aNewB2DPolyPolygon.count()) 1738 { 1739 // #i37011# 1740 bool bForceCreateTwoObjects(false); 1741 1742 if(!bSortFilledObjectsToBack && !aNewB2DPolyPolygon.isClosed() && !bNoStroke) 1743 { 1744 bForceCreateTwoObjects = true; 1745 } 1746 1747 if(bLineGeometryNeededOnly) 1748 { 1749 bForceCreateTwoObjects = true; 1750 bNoFill = true; 1751 bNoStroke = false; 1752 } 1753 1754 if(bForceCreateTwoObjects || bSortFilledObjectsToBack) 1755 { 1756 if(bFilled && !bNoFill) 1757 { 1758 basegfx::B2DPolyPolygon aClosedPolyPolygon(aNewB2DPolyPolygon); 1759 aClosedPolyPolygon.setClosed(true); 1760 SdrPathObj* pFill = new SdrPathObj(OBJ_POLY, aClosedPolyPolygon); 1761 SfxItemSet aTempSet(*this); 1762 aTempSet.Put(SdrShadowItem(sal_False)); 1763 aTempSet.Put(XLineStyleItem(XLINE_NONE)); 1764 pFill->SetMergedItemSet(aTempSet); 1765 rObjectList.push_back(pFill); 1766 } 1767 1768 if(!bNoStroke) 1769 { 1770 // there is no reason to use OBJ_PLIN here when the polygon is actually closed, 1771 // the non-fill is defined by XFILL_NONE. Since SdrPathObj::ImpForceKind() needs 1772 // to correct the polygon (here: open it) using the type, the last edge may get lost. 1773 // Thus, use a type that fits the polygon 1774 SdrPathObj* pStroke = new SdrPathObj( 1775 aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN, 1776 aNewB2DPolyPolygon); 1777 SfxItemSet aTempSet(*this); 1778 aTempSet.Put(SdrShadowItem(sal_False)); 1779 aTempSet.Put(XFillStyleItem(XFILL_NONE)); 1780 pStroke->SetMergedItemSet(aTempSet); 1781 rObjectList.push_back(pStroke); 1782 } 1783 } 1784 else 1785 { 1786 SdrPathObj* pObj = 0; 1787 SfxItemSet aTempSet(*this); 1788 aTempSet.Put(SdrShadowItem(sal_False)); 1789 1790 if(bNoFill) 1791 { 1792 // see comment above about OBJ_PLIN 1793 pObj = new SdrPathObj( 1794 aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN, 1795 aNewB2DPolyPolygon); 1796 aTempSet.Put(XFillStyleItem(XFILL_NONE)); 1797 } 1798 else 1799 { 1800 aNewB2DPolyPolygon.setClosed(true); 1801 pObj = new SdrPathObj(OBJ_POLY, aNewB2DPolyPolygon); 1802 } 1803 1804 if(bNoStroke) 1805 { 1806 aTempSet.Put(XLineStyleItem(XLINE_NONE)); 1807 } 1808 1809 if(pObj) 1810 { 1811 pObj->SetMergedItemSet(aTempSet); 1812 rObjectList.push_back(pObj); 1813 } 1814 } 1815 } 1816 } 1817 1818 void CorrectCalloutArrows( MSO_SPT eSpType, sal_uInt32 nLineObjectCount, std::vector< SdrPathObj* >& vObjectList ) 1819 { 1820 sal_Bool bAccent = sal_False; 1821 switch( eSpType ) 1822 { 1823 case mso_sptCallout1 : 1824 case mso_sptBorderCallout1 : 1825 case mso_sptCallout90 : 1826 case mso_sptBorderCallout90 : 1827 default: 1828 break; 1829 1830 case mso_sptAccentCallout1 : 1831 case mso_sptAccentBorderCallout1 : 1832 case mso_sptAccentCallout90 : 1833 case mso_sptAccentBorderCallout90 : 1834 { 1835 sal_uInt32 i, nLine = 0; 1836 for ( i = 0; i < vObjectList.size(); i++ ) 1837 { 1838 SdrPathObj* pObj( vObjectList[ i ] ); 1839 if(pObj->IsLine()) 1840 { 1841 nLine++; 1842 if ( nLine == nLineObjectCount ) 1843 { 1844 pObj->ClearMergedItem( XATTR_LINESTART ); 1845 pObj->ClearMergedItem( XATTR_LINEEND ); 1846 } 1847 } 1848 } 1849 } 1850 break; 1851 1852 // switch start & end 1853 case mso_sptAccentCallout2 : 1854 case mso_sptAccentBorderCallout2 : 1855 bAccent = sal_True; 1856 case mso_sptCallout2 : 1857 case mso_sptBorderCallout2 : 1858 { 1859 sal_uInt32 i, nLine = 0; 1860 for ( i = 0; i < vObjectList.size(); i++ ) 1861 { 1862 SdrPathObj* pObj( vObjectList[ i ] ); 1863 if(pObj->IsLine()) 1864 { 1865 nLine++; 1866 if ( nLine == 1 ) 1867 pObj->ClearMergedItem( XATTR_LINEEND ); 1868 else if ( ( bAccent && ( nLine == nLineObjectCount - 1 ) ) || ( !bAccent && ( nLine == nLineObjectCount ) ) ) 1869 pObj->ClearMergedItem( XATTR_LINESTART ); 1870 else 1871 { 1872 pObj->ClearMergedItem( XATTR_LINESTART ); 1873 pObj->ClearMergedItem( XATTR_LINEEND ); 1874 } 1875 } 1876 } 1877 } 1878 break; 1879 1880 case mso_sptAccentCallout3 : 1881 case mso_sptAccentBorderCallout3 : 1882 bAccent = sal_False; 1883 case mso_sptCallout3 : 1884 case mso_sptBorderCallout3 : 1885 { 1886 sal_uInt32 i, nLine = 0; 1887 for ( i = 0; i < vObjectList.size(); i++ ) 1888 { 1889 SdrPathObj* pObj( vObjectList[ i ] ); 1890 if(pObj->IsLine()) 1891 { 1892 if ( nLine ) 1893 { 1894 pObj->ClearMergedItem( XATTR_LINESTART ); 1895 pObj->ClearMergedItem( XATTR_LINEEND ); 1896 } 1897 else 1898 EnhancedCustomShape2d::SwapStartAndEndArrow( pObj ); 1899 1900 nLine++; 1901 } 1902 } 1903 } 1904 break; 1905 } 1906 } 1907 1908 void EnhancedCustomShape2d::AdaptObjColor(SdrPathObj& rObj, const SfxItemSet& rCustomShapeSet, 1909 sal_uInt32& nColorIndex, sal_uInt32 nColorCount) 1910 { 1911 if ( !rObj.IsLine() ) 1912 { 1913 const XFillStyle eFillStyle = ((const XFillStyleItem&)rObj.GetMergedItem(XATTR_FILLSTYLE)).GetValue(); 1914 switch( eFillStyle ) 1915 { 1916 default: 1917 case XFILL_SOLID: 1918 { 1919 Color aFillColor; 1920 if ( nColorCount ) 1921 { 1922 aFillColor = GetColorData( 1923 ((XFillColorItem&)rCustomShapeSet.Get( XATTR_FILLCOLOR )).GetColorValue(), 1924 std::min(nColorIndex, nColorCount-1) ); 1925 rObj.SetMergedItem( XFillColorItem( String(), aFillColor ) ); 1926 } 1927 break; 1928 } 1929 case XFILL_GRADIENT: 1930 { 1931 XGradient aXGradient(((const XFillGradientItem&)rObj.GetMergedItem(XATTR_FILLGRADIENT)).GetGradientValue()); 1932 if ( nColorCount ) 1933 { 1934 aXGradient.SetStartColor( 1935 GetColorData( 1936 aXGradient.GetStartColor(), 1937 std::min(nColorIndex, nColorCount-1) )); 1938 aXGradient.SetEndColor( 1939 GetColorData( 1940 aXGradient.GetEndColor(), 1941 std::min(nColorIndex, nColorCount-1) )); 1942 } 1943 1944 rObj.SetMergedItem( XFillGradientItem( String(), aXGradient ) ); 1945 break; 1946 } 1947 case XFILL_HATCH: 1948 { 1949 XHatch aXHatch(((const XFillHatchItem&)rObj.GetMergedItem(XATTR_FILLHATCH)).GetHatchValue()); 1950 if ( nColorCount ) 1951 { 1952 aXHatch.SetColor( 1953 GetColorData( 1954 aXHatch.GetColor(), 1955 std::min(nColorIndex, nColorCount-1) )); 1956 } 1957 1958 rObj.SetMergedItem( XFillHatchItem( String(), aXHatch ) ); 1959 break; 1960 } 1961 case XFILL_BITMAP: 1962 { 1963 Bitmap aBitmap(((const XFillBitmapItem&)rObj.GetMergedItem(XATTR_FILLBITMAP)).GetBitmapValue().GetBitmap()); 1964 if ( nColorCount ) 1965 { 1966 aBitmap.Adjust( 1967 static_cast< short > ( GetLuminanceChange( 1968 std::min(nColorIndex, nColorCount-1)))); 1969 } 1970 1971 rObj.SetMergedItem( XFillBitmapItem( String(), aBitmap ) ); 1972 break; 1973 } 1974 } 1975 1976 if ( nColorIndex < nColorCount ) 1977 nColorIndex++; 1978 } 1979 } 1980 1981 SdrObject* EnhancedCustomShape2d::CreatePathObj( sal_Bool bLineGeometryNeededOnly ) 1982 { 1983 sal_Int32 nCoordSize = seqCoordinates.getLength(); 1984 if ( !nCoordSize ) 1985 return NULL; 1986 1987 sal_uInt16 nSrcPt = 0; 1988 sal_uInt16 nSegmentInd = 0; 1989 1990 std::vector< SdrPathObj* > vObjectList; 1991 sal_Bool bSortFilledObjectsToBack = SortFilledObjectsToBackByDefault( eSpType ); 1992 1993 while( nSegmentInd <= seqSegments.getLength() ) 1994 { 1995 CreateSubPath( nSrcPt, nSegmentInd, vObjectList, bLineGeometryNeededOnly, bSortFilledObjectsToBack ); 1996 } 1997 1998 SdrObject* pRet = NULL; 1999 sal_uInt32 i; 2000 2001 if ( !vObjectList.empty() ) 2002 { 2003 const SfxItemSet& rCustomShapeSet = pCustomShapeObj->GetMergedItemSet(); 2004 Color aFillColor; 2005 sal_uInt32 nColorCount = nColorData >> 28; 2006 sal_uInt32 nColorIndex = 0; 2007 2008 // #i37011# remove invisible objects 2009 if(!vObjectList.empty()) 2010 { 2011 std::vector< SdrPathObj* > vTempList; 2012 2013 for(i = 0L; i < vObjectList.size(); i++) 2014 { 2015 SdrPathObj* pObj(vObjectList[i]); 2016 const XLineStyle eLineStyle = ((const XLineStyleItem&)pObj->GetMergedItem(XATTR_LINESTYLE)).GetValue(); 2017 const XFillStyle eFillStyle = ((const XFillStyleItem&)pObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue(); 2018 2019 //SJ: #i40600# if bLineGeometryNeededOnly is set linystyle does not matter 2020 if( !bLineGeometryNeededOnly && ( XLINE_NONE == eLineStyle ) && ( XFILL_NONE == eFillStyle ) ) 2021 delete pObj; 2022 else 2023 vTempList.push_back(pObj); 2024 } 2025 2026 vObjectList = vTempList; 2027 } 2028 2029 if(1L == vObjectList.size()) 2030 { 2031 // a single object, correct some values 2032 AdaptObjColor(*vObjectList[0L],rCustomShapeSet,nColorIndex,nColorCount); 2033 } 2034 else 2035 { 2036 sal_Int32 nLineObjectCount = 0; 2037 sal_Int32 nAreaObjectCount = 0; 2038 2039 // correct some values and collect content data 2040 for ( i = 0; i < vObjectList.size(); i++ ) 2041 { 2042 SdrPathObj* pObj( vObjectList[ i ] ); 2043 2044 if(pObj->IsLine()) 2045 { 2046 nLineObjectCount++; 2047 } 2048 else 2049 { 2050 nAreaObjectCount++; 2051 AdaptObjColor(*pObj,rCustomShapeSet,nColorIndex,nColorCount); 2052 } 2053 } 2054 2055 // #i88870# correct line arrows for callouts 2056 if ( nLineObjectCount ) 2057 CorrectCalloutArrows( eSpType, nLineObjectCount, vObjectList ); 2058 2059 // sort objects so that filled ones are in front. Necessary 2060 // for some strange objects 2061 if ( bSortFilledObjectsToBack ) 2062 { 2063 std::vector< SdrPathObj* > vTempList; 2064 2065 for ( i = 0; i < vObjectList.size(); i++ ) 2066 { 2067 SdrPathObj* pObj( vObjectList[ i ] ); 2068 2069 if ( !pObj->IsLine() ) 2070 { 2071 vTempList.push_back(pObj); 2072 } 2073 } 2074 2075 for ( i = 0; i < vObjectList.size(); i++ ) 2076 { 2077 SdrPathObj* pObj( vObjectList[ i ] ); 2078 2079 if ( pObj->IsLine() ) 2080 { 2081 vTempList.push_back(pObj); 2082 } 2083 } 2084 2085 vObjectList = vTempList; 2086 } 2087 } 2088 } 2089 2090 // #i37011# 2091 if(!vObjectList.empty()) 2092 { 2093 // copy remaining objects to pRet 2094 if(vObjectList.size() > 1L) 2095 { 2096 pRet = new SdrObjGroup; 2097 2098 for (i = 0L; i < vObjectList.size(); i++) 2099 { 2100 SdrObject* pObj(vObjectList[i]); 2101 pRet->GetSubList()->NbcInsertObject(pObj); 2102 } 2103 } 2104 else if(1L == vObjectList.size()) 2105 { 2106 pRet = vObjectList[0L]; 2107 } 2108 2109 if(pRet) 2110 { 2111 // move to target position 2112 Rectangle aCurRect(pRet->GetSnapRect()); 2113 aCurRect.Move(aLogicRect.Left(), aLogicRect.Top()); 2114 pRet->NbcSetSnapRect(aCurRect); 2115 } 2116 } 2117 2118 return pRet; 2119 } 2120 2121 SdrObject* EnhancedCustomShape2d::CreateObject( sal_Bool bLineGeometryNeededOnly ) 2122 { 2123 SdrObject* pRet = NULL; 2124 2125 if ( eSpType == mso_sptRectangle ) 2126 { 2127 pRet = new SdrRectObj( aLogicRect ); 2128 // SJ: not setting model, so we save a lot of broadcasting and the model is not modified any longer 2129 // pRet->SetModel( pCustomShapeObj->GetModel() ); 2130 pRet->SetMergedItemSet( *this ); 2131 } 2132 if ( !pRet ) 2133 pRet = CreatePathObj( bLineGeometryNeededOnly ); 2134 2135 return pRet; 2136 } 2137 2138 void EnhancedCustomShape2d::ApplyGluePoints( SdrObject* pObj ) 2139 { 2140 if ( pObj && seqGluePoints.getLength() ) 2141 { 2142 sal_uInt32 i, nCount = seqGluePoints.getLength(); 2143 for ( i = 0; i < nCount; i++ ) 2144 { 2145 SdrGluePoint aGluePoint; 2146 2147 aGluePoint.SetPos( GetPoint( seqGluePoints[ i ], sal_True, sal_True ) ); 2148 aGluePoint.SetPercent( sal_False ); 2149 2150 // const Point& rPoint = GetPoint( seqGluePoints[ i ], sal_True, sal_True ); 2151 // double fXRel = rPoint.X(); 2152 // double fYRel = rPoint.Y(); 2153 // fXRel = aLogicRect.GetWidth() == 0 ? 0.0 : fXRel / aLogicRect.GetWidth() * 10000; 2154 // fYRel = aLogicRect.GetHeight() == 0 ? 0.0 : fYRel / aLogicRect.GetHeight() * 10000; 2155 // aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) ); 2156 // aGluePoint.SetPercent( sal_True ); 2157 aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT ); 2158 aGluePoint.SetEscDir( SDRESC_SMART ); 2159 SdrGluePointList* pList = pObj->ForceGluePointList(); 2160 if( pList ) 2161 /* sal_uInt16 nId = */ pList->Insert( aGluePoint ); 2162 } 2163 } 2164 } 2165 2166 SdrObject* EnhancedCustomShape2d::CreateLineGeometry() 2167 { 2168 return CreateObject( sal_True ); 2169 } 2170 2171 2172