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