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_Int32 nP1, sal_Int32 nP2, sal_Int32 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_Int32 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 ( nPntCount ) 1501 { 1502 if(aNewB2DPolygon.count() > 1L) 1503 { 1504 // #i76201# Add conversion to closed polygon when first and last points are equal 1505 basegfx::tools::checkClosed(aNewB2DPolygon); 1506 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1507 } 1508 aNewB2DPolygon.clear(); 1509 } 1510 } 1511 case ANGLEELLIPSETO : 1512 { 1513 for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 2 ) < nCoordSize ); i++ ) 1514 { 1515 // create a circle 1516 Point _aCenter; 1517 double fWidth, fHeight; 1518 MSO_SPT eSpType = mso_sptEllipse; 1519 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType ); 1520 sal_Bool bIsDefaultViewBox = sal_False; 1521 sal_Bool bIsDefaultPath = sal_False; 1522 sal_Bool bIsMSEllipse = sal_False; 1523 1524 if( ( nCoordWidth == pDefCustomShape->nCoordWidth ) 1525 && ( nCoordHeight == pDefCustomShape->nCoordHeight ) ) 1526 bIsDefaultViewBox = sal_True; 1527 sal_Int32 j, nCount = pDefCustomShape->nVertices;//==3 1528 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2; 1529 1530 seqCoordinates1.realloc( nCount ); 1531 for ( j = 0; j < nCount; j++ ) 1532 { 1533 seqCoordinates1[j] = seqCoordinates[ rSrcPt + j]; 1534 } 1535 1536 seqCoordinates2.realloc( nCount ); 1537 for ( j = 0; j < nCount; j++ ) 1538 { 1539 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ j ].First, pDefCustomShape->pVertices[ j ].nValA ); 1540 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ j ].Second, pDefCustomShape->pVertices[ j ].nValB ); 1541 } 1542 if(seqCoordinates1 == seqCoordinates2) 1543 bIsDefaultPath = sal_True; 1544 1545 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 1546 rtl::OUString sShpType; 1547 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&)pCustomShapeObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 1548 Any* pAny = rGeometryItem.GetPropertyValueByName( sType ); 1549 if ( pAny ) 1550 *pAny >>= sShpType; 1551 if( sShpType.getLength() > 3 && 1552 sShpType.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "mso" ))){ 1553 bIsMSEllipse = sal_True; 1554 } 1555 if( (! bIsDefaultPath && ! bIsDefaultViewBox) || (bIsDefaultViewBox && bIsMSEllipse) /*&& (nGeneratorVersion == SfxObjectShell::Sym_L2)*/ ) 1556 { 1557 _aCenter = GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ); 1558 GetParameter( fWidth, seqCoordinates[ rSrcPt + 1 ].First, sal_True, sal_False ); 1559 GetParameter( fHeight, seqCoordinates[ rSrcPt + 1 ].Second, sal_False, sal_True ); 1560 fWidth /= 2; 1561 fHeight /= 2; 1562 }else if( bIsDefaultPath && !bIsDefaultViewBox /*&& (nGeneratorVersion == SfxObjectShell::Sym_L2)*/ ) 1563 { 1564 _aCenter.X() = nCoordWidth/2 * fXScale; 1565 _aCenter.Y() = nCoordHeight/2 * fYScale; 1566 fWidth = nCoordWidth/2; 1567 fHeight = nCoordHeight/2; 1568 1569 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) ); 1570 const Any* pViewBox = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sViewBox ); 1571 com::sun::star::awt::Rectangle aViewBox; 1572 if ( pViewBox && (*pViewBox >>= aViewBox ) ) 1573 { 1574 aViewBox.Width = pDefCustomShape->nCoordWidth; 1575 aViewBox.Height = pDefCustomShape->nCoordHeight; 1576 } 1577 com::sun::star::beans::PropertyValue aPropVal; 1578 aPropVal.Name = sViewBox; 1579 aPropVal.Value <<= aViewBox; 1580 rGeometryItem.SetPropertyValue( aPropVal ); 1581 pCustomShapeObj->SetMergedItem( rGeometryItem ); 1582 }else{ 1583 _aCenter = GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ); 1584 GetParameter( fWidth, seqCoordinates[ rSrcPt + 1 ].First, sal_True, sal_False ); 1585 GetParameter( fHeight, seqCoordinates[ rSrcPt + 1 ].Second, sal_False, sal_True ); 1586 } 1587 1588 fWidth *= fXScale; 1589 fHeight*= fYScale; 1590 Point aP( (sal_Int32)( _aCenter.X() - fWidth ), (sal_Int32)( _aCenter.Y() - fHeight ) ); 1591 Size aS( (sal_Int32)( fWidth * 2.0 ), (sal_Int32)( fHeight * 2.0 ) ); 1592 Rectangle aRect( aP, aS ); 1593 if ( aRect.GetWidth() && aRect.GetHeight() ) 1594 { 1595 double fStartAngle, fEndAngle; 1596 GetParameter( fStartAngle, seqCoordinates[ rSrcPt + 2 ].First, sal_False, sal_False ); 1597 GetParameter( fEndAngle , seqCoordinates[ rSrcPt + 2 ].Second, sal_False, sal_False ); 1598 1599 if ( ((sal_Int32)fStartAngle % 360) != ((sal_Int32)fEndAngle % 360) ) 1600 { 1601 if ( (sal_Int32)fStartAngle & 0x7fff0000 ) // SJ: if the angle was imported from our escher import, then the 1602 fStartAngle /= 65536.0; // value is shifted by 16. TODO: already change the fixed float to a 1603 if ( (sal_Int32)fEndAngle & 0x7fff0000 ) // double in the import filter 1604 { 1605 fEndAngle /= 65536.0; 1606 fEndAngle = fEndAngle + fStartAngle; 1607 if ( fEndAngle < 0 ) 1608 { // in the binary filter the endangle is the amount 1609 double fTemp = fStartAngle; 1610 fStartAngle = fEndAngle; 1611 fEndAngle = fTemp; 1612 } 1613 } 1614 double fCenterX = aRect.Center().X(); 1615 double fCenterY = aRect.Center().Y(); 1616 double fx1 = ( cos( fStartAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX; 1617 double fy1 = ( -sin( fStartAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY; 1618 double fx2 = ( cos( fEndAngle * F_PI180 ) * 65536.0 * fXScale ) + fCenterX; 1619 double fy2 = ( -sin( fEndAngle * F_PI180 ) * 65536.0 * fYScale ) + fCenterY; 1620 aNewB2DPolygon.append(CreateArc( aRect, Point( (sal_Int32)fx1, (sal_Int32)fy1 ), Point( (sal_Int32)fx2, (sal_Int32)fy2 ), sal_False)); 1621 } 1622 else 1623 { /* SJ: TODO: this block should be replaced sometimes, because the current point 1624 is not set correct, it also does not use the correct moveto 1625 point if ANGLEELLIPSETO was used, but the method CreateArc 1626 is at the moment not able to draw full circles (if startangle is 0 1627 and endangle 360 nothing is painted :-( */ 1628 sal_Int32 nXControl = (sal_Int32)((double)aRect.GetWidth() * 0.2835 ); 1629 sal_Int32 nYControl = (sal_Int32)((double)aRect.GetHeight() * 0.2835 ); 1630 Point aCenter( aRect.Center() ); 1631 1632 // append start point 1633 aNewB2DPolygon.append(basegfx::B2DPoint(aCenter.X(), aRect.Top())); 1634 1635 // append four bezier segments 1636 aNewB2DPolygon.appendBezierSegment( 1637 basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Top()), 1638 basegfx::B2DPoint(aRect.Right(), aCenter.Y() - nYControl), 1639 basegfx::B2DPoint(aRect.Right(), aCenter.Y())); 1640 1641 aNewB2DPolygon.appendBezierSegment( 1642 basegfx::B2DPoint(aRect.Right(), aCenter.Y() + nYControl), 1643 basegfx::B2DPoint(aCenter.X() + nXControl, aRect.Bottom()), 1644 basegfx::B2DPoint(aCenter.X(), aRect.Bottom())); 1645 1646 aNewB2DPolygon.appendBezierSegment( 1647 basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Bottom()), 1648 basegfx::B2DPoint(aRect.Left(), aCenter.Y() + nYControl), 1649 basegfx::B2DPoint(aRect.Left(), aCenter.Y())); 1650 1651 aNewB2DPolygon.appendBezierSegment( 1652 basegfx::B2DPoint(aRect.Left(), aCenter.Y() - nYControl), 1653 basegfx::B2DPoint(aCenter.X() - nXControl, aRect.Top()), 1654 basegfx::B2DPoint(aCenter.X(), aRect.Top())); 1655 1656 // close, rescue last controlpoint, remove double last point 1657 basegfx::tools::closeWithGeometryChange(aNewB2DPolygon); 1658 } 1659 } 1660 rSrcPt += 3; 1661 } 1662 } 1663 break; 1664 1665 case LINETO : 1666 { 1667 for ( sal_Int32 i(0L); ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ ) 1668 { 1669 const Point aTempPoint(GetPoint( seqCoordinates[ rSrcPt++ ], sal_True, sal_True )); 1670 aNewB2DPolygon.append(basegfx::B2DPoint(aTempPoint.X(), aTempPoint.Y())); 1671 } 1672 } 1673 break; 1674 1675 case ARC : 1676 case CLOCKWISEARC : 1677 { 1678 if(aNewB2DPolygon.count() > 1L) 1679 { 1680 // #i76201# Add conversion to closed polygon when first and last points are equal 1681 basegfx::tools::checkClosed(aNewB2DPolygon); 1682 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1683 } 1684 1685 aNewB2DPolygon.clear(); 1686 } 1687 case ARCTO : 1688 case CLOCKWISEARCTO : 1689 { 1690 sal_Bool bClockwise = ( nCommand == CLOCKWISEARC ) || ( nCommand == CLOCKWISEARCTO ); 1691 sal_uInt32 nXor = bClockwise ? 3 : 2; 1692 for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( ( rSrcPt + 3 ) < nCoordSize ); i++ ) 1693 { 1694 Rectangle aRect( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ), GetPoint( seqCoordinates[ rSrcPt + 1 ], sal_True, sal_True ) ); 1695 if ( aRect.GetWidth() && aRect.GetHeight() ) 1696 { 1697 Point aCenter( aRect.Center() ); 1698 Point aStart( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + nXor ) ], sal_True, sal_True ) ); 1699 Point aEnd( GetPoint( seqCoordinates[ (sal_uInt16)( rSrcPt + ( nXor ^ 1 ) ) ], sal_True, sal_True ) ); 1700 double fRatio = (double)aRect.GetHeight() / (double)aRect.GetWidth(); 1701 aStart.X() = (sal_Int32)( ( (double)( aStart.X() - aCenter.X() ) ) * fRatio ) + aCenter.X(); 1702 aStart.Y() = (sal_Int32)( ( (double)( aStart.Y() - aCenter.Y() ) ) ) + aCenter.Y(); 1703 aEnd.X() = (sal_Int32)( ( (double)( aEnd.X() - aCenter.X() ) ) * fRatio ) + aCenter.X(); 1704 aEnd.Y() = (sal_Int32)( ( (double)( aEnd.Y() - aCenter.Y() ) ) ) + aCenter.Y(); 1705 aNewB2DPolygon.append(CreateArc( aRect, aStart, aEnd, bClockwise)); 1706 } 1707 rSrcPt += 4; 1708 } 1709 } 1710 break; 1711 1712 case ELLIPTICALQUADRANTX : 1713 case ELLIPTICALQUADRANTY : 1714 { 1715 bool bFirstDirection(true); 1716 basegfx::B2DPoint aControlPointA; 1717 basegfx::B2DPoint aControlPointB; 1718 1719 for ( sal_uInt16 i = 0; ( i < nPntCount ) && ( rSrcPt < nCoordSize ); i++ ) 1720 { 1721 sal_uInt32 nModT = ( nCommand == ELLIPTICALQUADRANTX ) ? 1 : 0; 1722 Point aCurrent( GetPoint( seqCoordinates[ rSrcPt ], sal_True, sal_True ) ); 1723 1724 if ( rSrcPt ) // we need a previous point 1725 { 1726 Point aPrev( GetPoint( seqCoordinates[ rSrcPt - 1 ], sal_True, sal_True ) ); 1727 sal_Int32 nX, nY; 1728 nX = aCurrent.X() - aPrev.X(); 1729 nY = aCurrent.Y() - aPrev.Y(); 1730 if ( ( nY ^ nX ) & 0x80000000 ) 1731 { 1732 if ( !i ) 1733 bFirstDirection = true; 1734 else if ( !bFirstDirection ) 1735 nModT ^= 1; 1736 } 1737 else 1738 { 1739 if ( !i ) 1740 bFirstDirection = false; 1741 else if ( bFirstDirection ) 1742 nModT ^= 1; 1743 } 1744 if ( nModT ) // get the right corner 1745 { 1746 nX = aCurrent.X(); 1747 nY = aPrev.Y(); 1748 } 1749 else 1750 { 1751 nX = aPrev.X(); 1752 nY = aCurrent.Y(); 1753 } 1754 sal_Int32 nXVec = ( nX - aPrev.X() ) >> 1; 1755 sal_Int32 nYVec = ( nY - aPrev.Y() ) >> 1; 1756 Point aControl1( aPrev.X() + nXVec, aPrev.Y() + nYVec ); 1757 1758 aControlPointA = basegfx::B2DPoint(aControl1.X(), aControl1.Y()); 1759 1760 nXVec = ( nX - aCurrent.X() ) >> 1; 1761 nYVec = ( nY - aCurrent.Y() ) >> 1; 1762 Point aControl2( aCurrent.X() + nXVec, aCurrent.Y() + nYVec ); 1763 1764 aControlPointB = basegfx::B2DPoint(aControl2.X(), aControl2.Y()); 1765 1766 aNewB2DPolygon.appendBezierSegment( 1767 aControlPointA, 1768 aControlPointB, 1769 basegfx::B2DPoint(aCurrent.X(), aCurrent.Y())); 1770 } 1771 else 1772 { 1773 aNewB2DPolygon.append(basegfx::B2DPoint(aCurrent.X(), aCurrent.Y())); 1774 } 1775 1776 rSrcPt++; 1777 } 1778 } 1779 break; 1780 1781 #ifdef DBG_CUSTOMSHAPE 1782 case UNKNOWN : 1783 default : 1784 { 1785 ByteString aString( "CustomShapes::unknown PolyFlagValue :" ); 1786 aString.Append( ByteString::CreateFromInt32( nCommand ) ); 1787 DBG_ERROR( aString.GetBuffer() ); 1788 } 1789 break; 1790 #endif 1791 } 1792 if ( nCommand == ENDSUBPATH ) 1793 break; 1794 } 1795 } 1796 if ( rSegmentInd == nSegInfoSize ) 1797 rSegmentInd++; 1798 1799 if(aNewB2DPolygon.count() > 1L) 1800 { 1801 // #i76201# Add conversion to closed polygon when first and last points are equal 1802 basegfx::tools::checkClosed(aNewB2DPolygon); 1803 aNewB2DPolyPolygon.append(aNewB2DPolygon); 1804 } 1805 1806 if(aNewB2DPolyPolygon.count()) 1807 { 1808 // #i37011# 1809 bool bForceCreateTwoObjects(false); 1810 1811 if(!bSortFilledObjectsToBack && !aNewB2DPolyPolygon.isClosed() && !bNoStroke) 1812 { 1813 bForceCreateTwoObjects = true; 1814 } 1815 1816 if(bLineGeometryNeededOnly) 1817 { 1818 bForceCreateTwoObjects = true; 1819 bNoFill = true; 1820 bNoStroke = false; 1821 } 1822 1823 if(bForceCreateTwoObjects || bSortFilledObjectsToBack) 1824 { 1825 if(bFilled && !bNoFill) 1826 { 1827 basegfx::B2DPolyPolygon aClosedPolyPolygon(aNewB2DPolyPolygon); 1828 aClosedPolyPolygon.setClosed(true); 1829 SdrPathObj* pFill = new SdrPathObj(OBJ_POLY, aClosedPolyPolygon); 1830 SfxItemSet aTempSet(*this); 1831 aTempSet.Put(SdrShadowItem(sal_False)); 1832 aTempSet.Put(XLineStyleItem(XLINE_NONE)); 1833 pFill->SetMergedItemSet(aTempSet); 1834 rObjectList.push_back(pFill); 1835 } 1836 1837 if(!bNoStroke) 1838 { 1839 // there is no reason to use OBJ_PLIN here when the polygon is actually closed, 1840 // the non-fill is defined by XFILL_NONE. Since SdrPathObj::ImpForceKind() needs 1841 // to correct the polygon (here: open it) using the type, the last edge may get lost. 1842 // Thus, use a type that fits the polygon 1843 SdrPathObj* pStroke = new SdrPathObj( 1844 aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN, 1845 aNewB2DPolyPolygon); 1846 SfxItemSet aTempSet(*this); 1847 aTempSet.Put(SdrShadowItem(sal_False)); 1848 aTempSet.Put(XFillStyleItem(XFILL_NONE)); 1849 pStroke->SetMergedItemSet(aTempSet); 1850 rObjectList.push_back(pStroke); 1851 } 1852 } 1853 else 1854 { 1855 SdrPathObj* pObj = 0; 1856 SfxItemSet aTempSet(*this); 1857 aTempSet.Put(SdrShadowItem(sal_False)); 1858 1859 if(bNoFill) 1860 { 1861 // see comment above about OBJ_PLIN 1862 pObj = new SdrPathObj( 1863 aNewB2DPolyPolygon.isClosed() ? OBJ_POLY : OBJ_PLIN, 1864 aNewB2DPolyPolygon); 1865 aTempSet.Put(XFillStyleItem(XFILL_NONE)); 1866 } 1867 else 1868 { 1869 aNewB2DPolyPolygon.setClosed(true); 1870 pObj = new SdrPathObj(OBJ_POLY, aNewB2DPolyPolygon); 1871 } 1872 1873 if(bNoStroke) 1874 { 1875 aTempSet.Put(XLineStyleItem(XLINE_NONE)); 1876 } 1877 1878 if(pObj) 1879 { 1880 pObj->SetMergedItemSet(aTempSet); 1881 rObjectList.push_back(pObj); 1882 } 1883 } 1884 } 1885 } 1886 1887 void CorrectCalloutArrows( MSO_SPT eSpType, sal_uInt32 nLineObjectCount, std::vector< SdrPathObj* >& vObjectList ) 1888 { 1889 sal_Bool bAccent = sal_False; 1890 switch( eSpType ) 1891 { 1892 case mso_sptCallout1 : 1893 case mso_sptBorderCallout1 : 1894 case mso_sptCallout90 : 1895 case mso_sptBorderCallout90 : 1896 default: 1897 break; 1898 1899 case mso_sptAccentCallout1 : 1900 case mso_sptAccentBorderCallout1 : 1901 case mso_sptAccentCallout90 : 1902 case mso_sptAccentBorderCallout90 : 1903 { 1904 sal_uInt32 i, nLine = 0; 1905 for ( i = 0; i < vObjectList.size(); i++ ) 1906 { 1907 SdrPathObj* pObj( vObjectList[ i ] ); 1908 if(pObj->IsLine()) 1909 { 1910 nLine++; 1911 if ( nLine == nLineObjectCount ) 1912 { 1913 pObj->ClearMergedItem( XATTR_LINESTART ); 1914 pObj->ClearMergedItem( XATTR_LINEEND ); 1915 } 1916 } 1917 } 1918 } 1919 break; 1920 1921 // switch start & end 1922 case mso_sptAccentCallout2 : 1923 case mso_sptAccentBorderCallout2 : 1924 bAccent = sal_True; 1925 case mso_sptCallout2 : 1926 case mso_sptBorderCallout2 : 1927 { 1928 sal_uInt32 i, nLine = 0; 1929 for ( i = 0; i < vObjectList.size(); i++ ) 1930 { 1931 SdrPathObj* pObj( vObjectList[ i ] ); 1932 if(pObj->IsLine()) 1933 { 1934 nLine++; 1935 if ( nLine == 1 ) 1936 pObj->ClearMergedItem( XATTR_LINEEND ); 1937 else if ( ( bAccent && ( nLine == nLineObjectCount - 1 ) ) || ( !bAccent && ( nLine == nLineObjectCount ) ) ) 1938 pObj->ClearMergedItem( XATTR_LINESTART ); 1939 else 1940 { 1941 pObj->ClearMergedItem( XATTR_LINESTART ); 1942 pObj->ClearMergedItem( XATTR_LINEEND ); 1943 } 1944 } 1945 } 1946 } 1947 break; 1948 1949 case mso_sptAccentCallout3 : 1950 case mso_sptAccentBorderCallout3 : 1951 bAccent = sal_False; 1952 case mso_sptCallout3 : 1953 case mso_sptBorderCallout3 : 1954 { 1955 sal_uInt32 i, nLine = 0; 1956 for ( i = 0; i < vObjectList.size(); i++ ) 1957 { 1958 SdrPathObj* pObj( vObjectList[ i ] ); 1959 if(pObj->IsLine()) 1960 { 1961 if ( nLine ) 1962 { 1963 pObj->ClearMergedItem( XATTR_LINESTART ); 1964 pObj->ClearMergedItem( XATTR_LINEEND ); 1965 } 1966 else 1967 EnhancedCustomShape2d::SwapStartAndEndArrow( pObj ); 1968 1969 nLine++; 1970 } 1971 } 1972 } 1973 break; 1974 } 1975 } 1976 1977 void EnhancedCustomShape2d::AdaptObjColor(SdrPathObj& rObj, const SfxItemSet& rCustomShapeSet, 1978 sal_uInt32& nColorIndex, sal_uInt32 nColorCount) 1979 { 1980 if ( !rObj.IsLine() ) 1981 { 1982 const XFillStyle eFillStyle = ((const XFillStyleItem&)rObj.GetMergedItem(XATTR_FILLSTYLE)).GetValue(); 1983 switch( eFillStyle ) 1984 { 1985 default: 1986 case XFILL_SOLID: 1987 { 1988 Color aFillColor; 1989 if ( nColorCount ) 1990 { 1991 aFillColor = GetColorData( 1992 ((XFillColorItem&)rCustomShapeSet.Get( XATTR_FILLCOLOR )).GetColorValue(), 1993 std::min(nColorIndex, nColorCount-1) ); 1994 rObj.SetMergedItem( XFillColorItem( String(), aFillColor ) ); 1995 } 1996 break; 1997 } 1998 case XFILL_GRADIENT: 1999 { 2000 XGradient aXGradient(((const XFillGradientItem&)rObj.GetMergedItem(XATTR_FILLGRADIENT)).GetGradientValue()); 2001 if ( nColorCount ) 2002 { 2003 aXGradient.SetStartColor( 2004 GetColorData( 2005 aXGradient.GetStartColor(), 2006 std::min(nColorIndex, nColorCount-1) )); 2007 aXGradient.SetEndColor( 2008 GetColorData( 2009 aXGradient.GetEndColor(), 2010 std::min(nColorIndex, nColorCount-1) )); 2011 } 2012 2013 rObj.SetMergedItem( XFillGradientItem( String(), aXGradient ) ); 2014 break; 2015 } 2016 case XFILL_HATCH: 2017 { 2018 XHatch aXHatch(((const XFillHatchItem&)rObj.GetMergedItem(XATTR_FILLHATCH)).GetHatchValue()); 2019 if ( nColorCount ) 2020 { 2021 aXHatch.SetColor( 2022 GetColorData( 2023 aXHatch.GetColor(), 2024 std::min(nColorIndex, nColorCount-1) )); 2025 } 2026 2027 rObj.SetMergedItem( XFillHatchItem( String(), aXHatch ) ); 2028 break; 2029 } 2030 case XFILL_BITMAP: 2031 { 2032 if ( nColorCount ) 2033 { 2034 Bitmap aBitmap(((const XFillBitmapItem&)rObj.GetMergedItem(XATTR_FILLBITMAP)).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap()); 2035 2036 aBitmap.Adjust( 2037 static_cast< short > ( GetLuminanceChange( 2038 std::min(nColorIndex, nColorCount-1)))); 2039 2040 rObj.SetMergedItem(XFillBitmapItem(String(), Graphic(aBitmap))); 2041 } 2042 2043 break; 2044 } 2045 } 2046 2047 if ( nColorIndex < nColorCount ) 2048 nColorIndex++; 2049 } 2050 } 2051 2052 SdrObject* EnhancedCustomShape2d::CreatePathObj( sal_Bool bLineGeometryNeededOnly ) 2053 { 2054 sal_Int32 nCoordSize = seqCoordinates.getLength(); 2055 if ( !nCoordSize ) 2056 return NULL; 2057 2058 sal_uInt16 nSrcPt = 0; 2059 sal_uInt16 nSegmentInd = 0; 2060 2061 std::vector< SdrPathObj* > vObjectList; 2062 sal_Bool bSortFilledObjectsToBack = SortFilledObjectsToBackByDefault( eSpType ); 2063 2064 while( nSegmentInd <= seqSegments.getLength() ) 2065 { 2066 CreateSubPath( nSrcPt, nSegmentInd, vObjectList, bLineGeometryNeededOnly, bSortFilledObjectsToBack ); 2067 } 2068 2069 SdrObject* pRet = NULL; 2070 sal_uInt32 i; 2071 2072 if ( !vObjectList.empty() ) 2073 { 2074 const SfxItemSet& rCustomShapeSet = pCustomShapeObj->GetMergedItemSet(); 2075 Color aFillColor; 2076 sal_uInt32 nColorCount = nColorData >> 28; 2077 sal_uInt32 nColorIndex = 0; 2078 2079 // #i37011# remove invisible objects 2080 if(!vObjectList.empty()) 2081 { 2082 std::vector< SdrPathObj* > vTempList; 2083 2084 for(i = 0L; i < vObjectList.size(); i++) 2085 { 2086 SdrPathObj* pObj(vObjectList[i]); 2087 const XLineStyle eLineStyle = ((const XLineStyleItem&)pObj->GetMergedItem(XATTR_LINESTYLE)).GetValue(); 2088 const XFillStyle eFillStyle = ((const XFillStyleItem&)pObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue(); 2089 2090 //SJ: #i40600# if bLineGeometryNeededOnly is set linystyle does not matter 2091 if( !bLineGeometryNeededOnly && ( XLINE_NONE == eLineStyle ) && ( XFILL_NONE == eFillStyle ) ) 2092 delete pObj; 2093 else 2094 vTempList.push_back(pObj); 2095 } 2096 2097 vObjectList = vTempList; 2098 } 2099 2100 if(1L == vObjectList.size()) 2101 { 2102 // a single object, correct some values 2103 AdaptObjColor(*vObjectList[0L],rCustomShapeSet,nColorIndex,nColorCount); 2104 } 2105 else 2106 { 2107 sal_Int32 nLineObjectCount = 0; 2108 sal_Int32 nAreaObjectCount = 0; 2109 2110 // correct some values and collect content data 2111 for ( i = 0; i < vObjectList.size(); i++ ) 2112 { 2113 SdrPathObj* pObj( vObjectList[ i ] ); 2114 2115 if(pObj->IsLine()) 2116 { 2117 nLineObjectCount++; 2118 } 2119 else 2120 { 2121 nAreaObjectCount++; 2122 AdaptObjColor(*pObj,rCustomShapeSet,nColorIndex,nColorCount); 2123 } 2124 } 2125 2126 // #i88870# correct line arrows for callouts 2127 if ( nLineObjectCount ) 2128 CorrectCalloutArrows( eSpType, nLineObjectCount, vObjectList ); 2129 2130 // sort objects so that filled ones are in front. Necessary 2131 // for some strange objects 2132 if ( bSortFilledObjectsToBack ) 2133 { 2134 std::vector< SdrPathObj* > vTempList; 2135 2136 for ( i = 0; i < vObjectList.size(); i++ ) 2137 { 2138 SdrPathObj* pObj( vObjectList[ i ] ); 2139 2140 if ( !pObj->IsLine() ) 2141 { 2142 vTempList.push_back(pObj); 2143 } 2144 } 2145 2146 for ( i = 0; i < vObjectList.size(); i++ ) 2147 { 2148 SdrPathObj* pObj( vObjectList[ i ] ); 2149 2150 if ( pObj->IsLine() ) 2151 { 2152 vTempList.push_back(pObj); 2153 } 2154 } 2155 2156 vObjectList = vTempList; 2157 } 2158 } 2159 } 2160 2161 // #i37011# 2162 if(!vObjectList.empty()) 2163 { 2164 // copy remaining objects to pRet 2165 if(vObjectList.size() > 1L) 2166 { 2167 pRet = new SdrObjGroup; 2168 2169 for (i = 0L; i < vObjectList.size(); i++) 2170 { 2171 SdrObject* pObj(vObjectList[i]); 2172 pRet->GetSubList()->NbcInsertObject(pObj); 2173 } 2174 } 2175 else if(1L == vObjectList.size()) 2176 { 2177 pRet = vObjectList[0L]; 2178 } 2179 2180 if(pRet) 2181 { 2182 // move to target position 2183 Rectangle aCurRect(pRet->GetSnapRect()); 2184 aCurRect.Move(aLogicRect.Left(), aLogicRect.Top()); 2185 pRet->NbcSetSnapRect(aCurRect); 2186 } 2187 } 2188 2189 return pRet; 2190 } 2191 2192 SdrObject* EnhancedCustomShape2d::CreateObject( sal_Bool bLineGeometryNeededOnly ) 2193 { 2194 SdrObject* pRet = NULL; 2195 2196 if ( eSpType == mso_sptRectangle ) 2197 { 2198 pRet = new SdrRectObj( aLogicRect ); 2199 // SJ: not setting model, so we save a lot of broadcasting and the model is not modified any longer 2200 // pRet->SetModel( pCustomShapeObj->GetModel() ); 2201 pRet->SetMergedItemSet( *this ); 2202 } 2203 if ( !pRet ) 2204 pRet = CreatePathObj( bLineGeometryNeededOnly ); 2205 2206 return pRet; 2207 } 2208 2209 void EnhancedCustomShape2d::ApplyGluePoints( SdrObject* pObj ) 2210 { 2211 if ( pObj && seqGluePoints.getLength() ) 2212 { 2213 sal_uInt32 i, nCount = seqGluePoints.getLength(); 2214 for ( i = 0; i < nCount; i++ ) 2215 { 2216 SdrGluePoint aGluePoint; 2217 2218 aGluePoint.SetPos( GetPoint( seqGluePoints[ i ], sal_True, sal_True ) ); 2219 aGluePoint.SetPercent( sal_False ); 2220 2221 // const Point& rPoint = GetPoint( seqGluePoints[ i ], sal_True, sal_True ); 2222 // double fXRel = rPoint.X(); 2223 // double fYRel = rPoint.Y(); 2224 // fXRel = aLogicRect.GetWidth() == 0 ? 0.0 : fXRel / aLogicRect.GetWidth() * 10000; 2225 // fYRel = aLogicRect.GetHeight() == 0 ? 0.0 : fYRel / aLogicRect.GetHeight() * 10000; 2226 // aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) ); 2227 // aGluePoint.SetPercent( sal_True ); 2228 aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT ); 2229 aGluePoint.SetEscDir( SDRESC_SMART ); 2230 SdrGluePointList* pList = pObj->ForceGluePointList(); 2231 if( pList ) 2232 /* sal_uInt16 nId = */ pList->Insert( aGluePoint ); 2233 } 2234 } 2235 } 2236 2237 SdrObject* EnhancedCustomShape2d::CreateLineGeometry() 2238 { 2239 return CreateObject( sal_True ); 2240 } 2241 2242 2243