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