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