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_filter.hxx" 26 #include "eschesdo.hxx" 27 #include <svx/svdomedia.hxx> 28 #include <svx/xflftrit.hxx> 29 #include <filter/msfilter/escherex.hxx> 30 #include <svx/unoapi.hxx> 31 #include <svx/svdobj.hxx> 32 #include <svx/svdoashp.hxx> 33 #include <svx/svdoole2.hxx> 34 #include <svx/svdmodel.hxx> 35 #include <editeng/outlobj.hxx> 36 #include <vcl/gradient.hxx> 37 #include <vcl/graph.hxx> 38 #include <vcl/cvtgrf.hxx> 39 #include <vcl/svapp.hxx> 40 #include <vcl/wrkwin.hxx> 41 #include <tools/stream.hxx> 42 #include <tools/zcodec.hxx> 43 #include <svx/svdopath.hxx> 44 #include <stdlib.h> 45 #include <svtools/filter.hxx> 46 #include "svx/EnhancedCustomShapeTypeNames.hxx" 47 #include "svx/EnhancedCustomShapeGeometry.hxx" 48 #include <svx/EnhancedCustomShapeFunctionParser.hxx> 49 #include "svx/EnhancedCustomShape2d.hxx" 50 #include <com/sun/star/beans/PropertyValues.hpp> 51 #include <com/sun/star/beans/XPropertyState.hpp> 52 #include <com/sun/star/awt/GradientStyle.hpp> 53 #include <com/sun/star/awt/RasterOperation.hpp> 54 #include <com/sun/star/awt/Gradient.hpp> 55 #include <com/sun/star/drawing/LineStyle.hpp> 56 #include <com/sun/star/drawing/LineJoint.hpp> 57 #include <com/sun/star/drawing/LineCap.hpp> 58 #include <com/sun/star/drawing/FillStyle.hpp> 59 #include <com/sun/star/drawing/LineDash.hpp> 60 #include <com/sun/star/drawing/BezierPoint.hpp> 61 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> 62 #include <com/sun/star/drawing/ConnectorType.hpp> 63 #include <com/sun/star/drawing/ConnectionType.hpp> 64 #include <com/sun/star/drawing/CircleKind.hpp> 65 #include <com/sun/star/drawing/PointSequence.hpp> 66 #include <com/sun/star/drawing/FlagSequence.hpp> 67 #include <com/sun/star/drawing/PolygonFlags.hpp> 68 #include <com/sun/star/text/WritingMode.hpp> 69 #include <com/sun/star/drawing/TextVerticalAdjust.hpp> 70 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp> 71 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp> 72 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp> 73 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp> 74 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp> 75 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp> 76 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> 77 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp> 78 #include <com/sun/star/drawing/ProjectionMode.hpp> 79 #include <com/sun/star/text/XSimpleText.hpp> 80 #include <com/sun/star/drawing/ShadeMode.hpp> 81 #include <com/sun/star/drawing/TextFitToSizeType.hpp> 82 #include <vcl/hatch.hxx> 83 #include <com/sun/star/awt/XGraphics.hpp> 84 #include <com/sun/star/awt/FontSlant.hpp> 85 #include <com/sun/star/awt/FontWeight.hpp> 86 #include <com/sun/star/drawing/ColorMode.hpp> 87 #include <com/sun/star/drawing/Position3D.hpp> 88 #include <com/sun/star/drawing/Direction3D.hpp> 89 #include <com/sun/star/text/GraphicCrop.hpp> 90 #include <unotools/ucbstreamhelper.hxx> 91 #include <unotools/localfilehelper.hxx> 92 #include <comphelper/extract.hxx> 93 #include <toolkit/unohlp.hxx> 94 #include <vcl/virdev.hxx> 95 #include <rtl/crc.h> 96 #include <vos/xception.hxx> 97 using namespace vos; 98 99 using namespace ::rtl; 100 using namespace ::com::sun::star; 101 102 103 // --------------------------------------------------------------------------------------------- 104 105 EscherExContainer::EscherExContainer( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance ) : 106 rStrm ( rSt ) 107 { 108 rStrm << (sal_uInt32)( ( 0xf | ( nInstance << 4 ) ) | ( nRecType << 16 ) ) << (sal_uInt32)0; 109 nContPos = rStrm.Tell(); 110 } 111 EscherExContainer::~EscherExContainer() 112 { 113 sal_uInt32 nPos = rStrm.Tell(); 114 sal_uInt32 nSize= nPos - nContPos; 115 if ( nSize ) 116 { 117 rStrm.Seek( nContPos - 4 ); 118 rStrm << nSize; 119 rStrm.Seek( nPos ); 120 } 121 } 122 123 EscherExAtom::EscherExAtom( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance, const sal_uInt8 nVersion ) : 124 rStrm ( rSt ) 125 { 126 rStrm << (sal_uInt32)( ( nVersion | ( nInstance << 4 ) ) | ( nRecType << 16 ) ) << (sal_uInt32)0; 127 nContPos = rStrm.Tell(); 128 } 129 EscherExAtom::~EscherExAtom() 130 { 131 sal_uInt32 nPos = rStrm.Tell(); 132 sal_uInt32 nSize= nPos - nContPos; 133 if ( nSize ) 134 { 135 rStrm.Seek( nContPos - 4 ); 136 rStrm << nSize; 137 rStrm.Seek( nPos ); 138 } 139 } 140 141 // --------------------------------------------------------------------------------------------- 142 143 EscherExClientRecord_Base::~EscherExClientRecord_Base() 144 { 145 } 146 147 EscherExClientAnchor_Base::~EscherExClientAnchor_Base() 148 { 149 } 150 151 // --------------------------------------------------------------------------------------------- 152 153 void EscherPropertyContainer::ImplInit() 154 { 155 nSortCount = 0; 156 nCountCount = 0; 157 nCountSize = 0; 158 nSortBufSize = 64; 159 bHasComplexData = sal_False; 160 bSuppressRotation = sal_False; 161 pSortStruct = new EscherPropSortStruct[ nSortBufSize ]; 162 } 163 164 EscherPropertyContainer::EscherPropertyContainer() : 165 pGraphicProvider ( NULL ), 166 pPicOutStrm ( NULL ) 167 { 168 ImplInit(); 169 }; 170 171 EscherPropertyContainer::EscherPropertyContainer( 172 EscherGraphicProvider& rGraphProv, 173 SvStream* pPiOutStrm, 174 Rectangle& rBoundRect ) : 175 176 pGraphicProvider ( &rGraphProv ), 177 pPicOutStrm ( pPiOutStrm ), 178 pShapeBoundRect ( &rBoundRect ) 179 { 180 ImplInit(); 181 } 182 183 EscherPropertyContainer::~EscherPropertyContainer() 184 { 185 if ( bHasComplexData ) 186 { 187 while ( nSortCount-- ) 188 delete[] pSortStruct[ nSortCount ].pBuf; 189 } 190 delete[] pSortStruct; 191 }; 192 193 void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, sal_uInt32 nPropValue, sal_Bool bBlib ) 194 { 195 AddOpt( nPropID, bBlib, nPropValue, NULL, 0 ); 196 } 197 198 void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, const rtl::OUString& rString ) 199 { 200 sal_Int32 j, i, nLen = rString.getLength() * 2 + 2; 201 sal_uInt8* pBuf = new sal_uInt8[ nLen ]; 202 for ( j = i = 0; i < rString.getLength(); i++ ) 203 { 204 sal_uInt16 nChar = (sal_uInt16)rString[ i ]; 205 pBuf[ j++ ] = (sal_uInt8)nChar; 206 pBuf[ j++ ] = (sal_uInt8)( nChar >> 8 ); 207 } 208 pBuf[ j++ ] = 0; 209 pBuf[ j++ ] = 0; 210 AddOpt( nPropID, sal_True, nLen, pBuf, nLen ); 211 } 212 213 void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, sal_Bool bBlib, sal_uInt32 nPropValue, sal_uInt8* pProp, sal_uInt32 nPropSize ) 214 { 215 if ( bBlib ) // bBlib is only valid when fComplex = 0 216 nPropID |= 0x4000; 217 if ( pProp ) 218 nPropID |= 0x8000; // fComplex = sal_True; 219 220 sal_uInt32 i; 221 for( i = 0; i < nSortCount; i++ ) 222 { 223 if ( ( pSortStruct[ i ].nPropId &~0xc000 ) == ( nPropID &~0xc000 ) ) // pruefen, ob Property nur ersetzt wird 224 { 225 pSortStruct[ i ].nPropId = nPropID; 226 if ( pSortStruct[ i ].pBuf ) 227 { 228 nCountSize -= pSortStruct[ i ].nPropSize; 229 delete[] pSortStruct[ i ].pBuf; 230 } 231 pSortStruct[ i ].pBuf = pProp; 232 pSortStruct[ i ].nPropSize = nPropSize; 233 pSortStruct[ i ].nPropValue = nPropValue; 234 if ( pProp ) 235 nCountSize += nPropSize; 236 return; 237 } 238 } 239 nCountCount++; 240 nCountSize += 6; 241 if ( nSortCount == nSortBufSize ) // buffer vergroessern 242 { 243 nSortBufSize <<= 1; 244 EscherPropSortStruct* pTemp = new EscherPropSortStruct[ nSortBufSize ]; 245 for( i = 0; i < nSortCount; i++ ) 246 { 247 pTemp[ i ] = pSortStruct[ i ]; 248 } 249 delete pSortStruct; 250 pSortStruct = pTemp; 251 } 252 pSortStruct[ nSortCount ].nPropId = nPropID; // property einfuegen 253 pSortStruct[ nSortCount ].pBuf = pProp; 254 pSortStruct[ nSortCount ].nPropSize = nPropSize; 255 pSortStruct[ nSortCount++ ].nPropValue = nPropValue; 256 257 if ( pProp ) 258 { 259 nCountSize += nPropSize; 260 bHasComplexData = sal_True; 261 } 262 } 263 264 sal_Bool EscherPropertyContainer::GetOpt( sal_uInt16 nPropId, sal_uInt32& rPropValue ) const 265 { 266 EscherPropSortStruct aPropStruct; 267 268 if ( GetOpt( nPropId, aPropStruct ) ) 269 { 270 rPropValue = aPropStruct.nPropValue; 271 return sal_True; 272 } 273 return sal_False; 274 } 275 276 sal_Bool EscherPropertyContainer::GetOpt( sal_uInt16 nPropId, EscherPropSortStruct& rPropValue ) const 277 { 278 for( sal_uInt32 i = 0; i < nSortCount; i++ ) 279 { 280 if ( ( pSortStruct[ i ].nPropId &~0xc000 ) == ( nPropId &~0xc000 ) ) 281 { 282 rPropValue = pSortStruct[ i ]; 283 return sal_True; 284 } 285 } 286 return sal_False; 287 } 288 289 EscherProperties EscherPropertyContainer::GetOpts() const 290 { 291 EscherProperties aVector; 292 293 for ( sal_uInt32 i = 0; i < nSortCount; ++i ) 294 aVector.push_back( pSortStruct[ i ] ); 295 296 return aVector; 297 } 298 299 extern "C" int __LOADONCALLAPI EscherPropSortFunc( const void* p1, const void* p2 ) 300 { 301 sal_Int16 nID1 = ((EscherPropSortStruct*)p1)->nPropId &~0xc000; 302 sal_Int16 nID2 = ((EscherPropSortStruct*)p2)->nPropId &~0xc000; 303 304 if( nID1 < nID2 ) 305 return -1; 306 else if( nID1 > nID2 ) 307 return 1; 308 else 309 return 0; 310 } 311 312 void EscherPropertyContainer::Commit( SvStream& rSt, sal_uInt16 nVersion, sal_uInt16 nRecType ) 313 { 314 rSt << (sal_uInt16)( ( nCountCount << 4 ) | ( nVersion & 0xf ) ) << nRecType << nCountSize; 315 if ( nSortCount ) 316 { 317 qsort( pSortStruct, nSortCount, sizeof( EscherPropSortStruct ), EscherPropSortFunc ); 318 sal_uInt32 i; 319 320 for ( i = 0; i < nSortCount; i++ ) 321 { 322 sal_uInt32 nPropValue = pSortStruct[ i ].nPropValue; 323 sal_uInt16 nPropId = pSortStruct[ i ].nPropId; 324 325 if ( bSuppressRotation && ( nPropId == ESCHER_Prop_Rotation ) ) 326 nPropValue = 0; 327 328 rSt << nPropId 329 << nPropValue; 330 } 331 if ( bHasComplexData ) 332 { 333 for ( i = 0; i < nSortCount; i++ ) 334 { 335 if ( pSortStruct[ i ].pBuf ) 336 rSt.Write( pSortStruct[ i ].pBuf, pSortStruct[ i ].nPropSize ); 337 } 338 } 339 } 340 } 341 342 sal_Bool EscherPropertyContainer::IsFontWork() const 343 { 344 sal_uInt32 nTextPathFlags = 0; 345 GetOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags ); 346 return ( nTextPathFlags & 0x4000 ) != 0; 347 } 348 349 sal_uInt32 EscherPropertyContainer::ImplGetColor( const sal_uInt32 nSOColor, sal_Bool bSwap ) 350 { 351 if ( bSwap ) 352 { 353 sal_uInt32 nColor = nSOColor & 0xff00; // GRUEN 354 nColor |= (sal_uInt8)( nSOColor ) << 16; // ROT 355 nColor |= (sal_uInt8)( nSOColor >> 16 ); // BLAU 356 return nColor; 357 } 358 else 359 return nSOColor & 0xffffff; 360 } 361 362 sal_uInt32 EscherPropertyContainer::GetGradientColor( 363 const ::com::sun::star::awt::Gradient* pGradient, 364 sal_uInt32 nStartColor ) 365 { 366 sal_uInt32 nIntensity = 100; 367 Color aColor; 368 369 if ( pGradient ) 370 { 371 if ( nStartColor & 1 ) 372 { 373 nIntensity = pGradient->StartIntensity; 374 aColor = pGradient->StartColor; 375 } 376 else 377 { 378 nIntensity = pGradient->EndIntensity; 379 aColor = pGradient->EndColor; 380 } 381 } 382 sal_uInt32 nRed = ( ( aColor.GetRed() * nIntensity ) / 100 ); 383 sal_uInt32 nGreen = ( ( aColor.GetGreen() * nIntensity ) / 100 ) << 8; 384 sal_uInt32 nBlue = ( ( aColor.GetBlue() * nIntensity ) / 100 ) << 16; 385 return nRed | nGreen | nBlue; 386 } 387 388 void EscherPropertyContainer::CreateGradientProperties( 389 const ::com::sun::star::awt::Gradient & rGradient ) 390 { 391 sal_uInt32 nFillType = ESCHER_FillShadeScale; 392 sal_uInt32 nAngle = 0; 393 sal_uInt32 nFillFocus = 0; 394 sal_uInt32 nFillLR = 0; 395 sal_uInt32 nFillTB = 0; 396 sal_uInt32 nFirstColor = 0; 397 bool bWriteFillTo = false; 398 399 switch ( rGradient.Style ) 400 { 401 case ::com::sun::star::awt::GradientStyle_LINEAR : 402 case ::com::sun::star::awt::GradientStyle_AXIAL : 403 { 404 nFillType = ESCHER_FillShadeScale; 405 nAngle = (rGradient.Angle * 0x10000) / 10; 406 nFillFocus = (sal::static_int_cast<int>(rGradient.Style) == 407 sal::static_int_cast<int>(GradientStyle_LINEAR)) ? 0 : 50; 408 } 409 break; 410 case ::com::sun::star::awt::GradientStyle_RADIAL : 411 case ::com::sun::star::awt::GradientStyle_ELLIPTICAL : 412 case ::com::sun::star::awt::GradientStyle_SQUARE : 413 case ::com::sun::star::awt::GradientStyle_RECT : 414 { 415 nFillLR = (rGradient.XOffset * 0x10000) / 100; 416 nFillTB = (rGradient.YOffset * 0x10000) / 100; 417 if ( ((nFillLR > 0) && (nFillLR < 0x10000)) || ((nFillTB > 0) && (nFillTB < 0x10000)) ) 418 nFillType = ESCHER_FillShadeShape; 419 else 420 nFillType = ESCHER_FillShadeCenter; 421 nFirstColor = 1; 422 bWriteFillTo = true; 423 } 424 break; 425 case ::com::sun::star::awt::GradientStyle_MAKE_FIXED_SIZE : break; 426 } 427 AddOpt( ESCHER_Prop_fillType, nFillType ); 428 AddOpt( ESCHER_Prop_fillAngle, nAngle ); 429 AddOpt( ESCHER_Prop_fillColor, GetGradientColor( &rGradient, nFirstColor ) ); 430 AddOpt( ESCHER_Prop_fillBackColor, GetGradientColor( &rGradient, nFirstColor ^ 1 ) ); 431 AddOpt( ESCHER_Prop_fillFocus, nFillFocus ); 432 if ( bWriteFillTo ) 433 { 434 AddOpt( ESCHER_Prop_fillToLeft, nFillLR ); 435 AddOpt( ESCHER_Prop_fillToTop, nFillTB ); 436 AddOpt( ESCHER_Prop_fillToRight, nFillLR ); 437 AddOpt( ESCHER_Prop_fillToBottom, nFillTB ); 438 } 439 } 440 441 void EscherPropertyContainer::CreateGradientProperties( 442 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet , sal_Bool bTransparentGradient) 443 { 444 ::com::sun::star::uno::Any aAny; 445 ::com::sun::star::awt::Gradient* pGradient = NULL; 446 447 sal_uInt32 nFillType = ESCHER_FillShadeScale; 448 sal_Int32 nAngle = 0; 449 sal_uInt32 nFillFocus = 0; 450 sal_uInt32 nFillLR = 0; 451 sal_uInt32 nFillTB = 0; 452 sal_uInt32 nFirstColor = 0;//like the control var nChgColors in import logic 453 bool bWriteFillTo = false; 454 455 //Transparency gradient: Means the third setting in transparency page is set 456 if (bTransparentGradient && EscherPropertyValueHelper::GetPropertyValue( 457 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillTransparenceGradient" ) ), sal_False ) ) 458 { 459 pGradient = (::com::sun::star::awt::Gradient*)aAny.getValue(); 460 461 ::com::sun::star::uno::Any aAnyTemp; 462 const rtl::OUString aPropName( String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ); 463 if ( EscherPropertyValueHelper::GetPropertyValue( 464 aAnyTemp, rXPropSet, aPropName, sal_False ) ) 465 { 466 ::com::sun::star::drawing::FillStyle eFS; 467 if ( ! ( aAnyTemp >>= eFS ) ) 468 eFS = ::com::sun::star::drawing::FillStyle_SOLID; 469 //solid and transparency 470 if ( eFS == ::com::sun::star::drawing::FillStyle_SOLID) 471 { 472 if ( EscherPropertyValueHelper::GetPropertyValue( 473 aAnyTemp, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False ) ) 474 { 475 pGradient->StartColor = ImplGetColor( *((sal_uInt32*)aAnyTemp.getValue()), sal_False ); 476 pGradient->EndColor = ImplGetColor( *((sal_uInt32*)aAnyTemp.getValue()), sal_False ); 477 } 478 } 479 //gradient and transparency. 480 else if( eFS == ::com::sun::star::drawing::FillStyle_GRADIENT ) 481 { 482 if ( EscherPropertyValueHelper::GetPropertyValue( 483 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ), sal_False ) ) 484 pGradient = (::com::sun::star::awt::Gradient*)aAny.getValue(); 485 } 486 } 487 488 } 489 //Not transparency gradient 490 else if ( EscherPropertyValueHelper::GetPropertyValue( 491 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ), sal_False ) ) 492 { 493 pGradient = (::com::sun::star::awt::Gradient*)aAny.getValue(); 494 } 495 496 if ( pGradient ) 497 { 498 switch ( pGradient->Style ) 499 { 500 case ::com::sun::star::awt::GradientStyle_LINEAR : 501 case ::com::sun::star::awt::GradientStyle_AXIAL : 502 { 503 nFillType = ESCHER_FillShadeScale; 504 nAngle = pGradient->Angle; 505 while ( nAngle > 0 ) nAngle -= 3600; 506 while ( nAngle <= -3600 ) nAngle += 3600; 507 //Value of the real number = Integral + (Fractional / 65536.0) 508 nAngle = ( nAngle * 0x10000) / 10; 509 510 nFillFocus = (pGradient->Style == ::com::sun::star::awt::GradientStyle_LINEAR) ? 511 ( pGradient->XOffset + pGradient->YOffset )/2 : -50; 512 if( !nFillFocus ) 513 nFirstColor=nFirstColor ^ 1; 514 if ( !nAngle ) 515 nFirstColor=nFirstColor ^ 1; 516 } 517 break; 518 case ::com::sun::star::awt::GradientStyle_RADIAL : 519 case ::com::sun::star::awt::GradientStyle_ELLIPTICAL : 520 case ::com::sun::star::awt::GradientStyle_SQUARE : 521 case ::com::sun::star::awt::GradientStyle_RECT : 522 { 523 //according to the import logic and rect type fill** value 524 nFillLR = (pGradient->XOffset * 0x10000) / 100; 525 nFillTB = (pGradient->YOffset * 0x10000) / 100; 526 if ( ((nFillLR > 0) && (nFillLR < 0x10000)) || ((nFillTB > 0) && (nFillTB < 0x10000)) ) 527 nFillType = ESCHER_FillShadeShape; 528 else 529 nFillType = ESCHER_FillShadeCenter; 530 nFirstColor = 1; 531 bWriteFillTo = true; 532 } 533 break; 534 default: break; 535 } 536 } 537 538 AddOpt( ESCHER_Prop_fillType, nFillType ); 539 AddOpt( ESCHER_Prop_fillAngle, nAngle ); 540 AddOpt( ESCHER_Prop_fillColor, GetGradientColor( pGradient, nFirstColor ) ); 541 AddOpt( ESCHER_Prop_fillBackColor, GetGradientColor( pGradient, nFirstColor ^ 1 ) ); 542 AddOpt( ESCHER_Prop_fillFocus, nFillFocus ); 543 if ( bWriteFillTo ) 544 { 545 //according to rect type fillTo** value 546 if(nFillLR) 547 { 548 AddOpt( ESCHER_Prop_fillToLeft, nFillLR ); 549 AddOpt( ESCHER_Prop_fillToRight, nFillLR ); 550 } 551 if(nFillTB) 552 { 553 AddOpt( ESCHER_Prop_fillToTop, nFillTB ); 554 AddOpt( ESCHER_Prop_fillToBottom, nFillTB ); 555 } 556 } 557 558 //Transparency gradient 559 if (bTransparentGradient && EscherPropertyValueHelper::GetPropertyValue( 560 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillTransparenceGradient" ) ), sal_False ) ) 561 { 562 pGradient = (::com::sun::star::awt::Gradient*)aAny.getValue(); 563 if ( pGradient ) 564 { 565 sal_uInt32 nBlue = GetGradientColor( pGradient, nFirstColor ) >> 16; 566 AddOpt( ESCHER_Prop_fillOpacity,( ( 100 - ( nBlue * 100 / 255 ) ) << 16 ) / 100 ); 567 nBlue = GetGradientColor( pGradient, nFirstColor ^ 1 ) >>16 ; 568 AddOpt( ESCHER_Prop_fillBackOpacity,( ( 100 - ( nBlue * 100 / 255 ) ) << 16 )/ 100 ); 569 } 570 } 571 } 572 573 void EscherPropertyContainer::CreateFillProperties( 574 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 575 sal_Bool bEdge , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) 576 { 577 if ( rXShape.is() ) 578 { 579 SdrObject* pObj = GetSdrObjectFromXShape( rXShape ); 580 if ( pObj ) 581 { 582 SfxItemSet aAttr( pObj->GetMergedItemSet() ); 583 //tranparency with gradient. Means the third setting in transparency page is set 584 sal_Bool bTransparentGradient = ( aAttr.GetItemState( XATTR_FILLFLOATTRANSPARENCE ) == SFX_ITEM_SET ) && 585 ( (const XFillFloatTransparenceItem&) aAttr.Get( XATTR_FILLFLOATTRANSPARENCE ) ).IsEnabled(); 586 CreateFillProperties( rXPropSet, bEdge, bTransparentGradient ); 587 } 588 } 589 } 590 591 void EscherPropertyContainer::CreateFillProperties( 592 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 593 sal_Bool bEdge , sal_Bool bTransparentGradient) 594 595 { 596 ::com::sun::star::uno::Any aAny; 597 AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone ); 598 AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle ); 599 600 sal_uInt32 nFillBackColor = 0; 601 602 const rtl::OUString aPropName( String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) ); 603 if ( EscherPropertyValueHelper::GetPropertyValue( 604 aAny, rXPropSet, aPropName, sal_False ) ) 605 { 606 ::com::sun::star::drawing::FillStyle eFS; 607 if ( ! ( aAny >>= eFS ) ) 608 eFS = ::com::sun::star::drawing::FillStyle_SOLID; 609 switch( eFS ) 610 { 611 case ::com::sun::star::drawing::FillStyle_GRADIENT : 612 { 613 CreateGradientProperties( rXPropSet , bTransparentGradient ); 614 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 ); 615 } 616 break; 617 618 case ::com::sun::star::drawing::FillStyle_BITMAP : 619 { 620 CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ), sal_True ); 621 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 ); 622 AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor ); 623 } 624 break; 625 case ::com::sun::star::drawing::FillStyle_HATCH : 626 { 627 CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ), sal_True ); 628 } 629 break; 630 case ::com::sun::star::drawing::FillStyle_SOLID : 631 default: 632 { 633 if ( bTransparentGradient ) 634 CreateGradientProperties( rXPropSet , bTransparentGradient ); 635 else 636 { 637 ::com::sun::star::beans::PropertyState ePropState = EscherPropertyValueHelper::GetPropertyState( 638 rXPropSet, aPropName ); 639 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE ) 640 AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid ); 641 642 if ( EscherPropertyValueHelper::GetPropertyValue( 643 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False ) ) 644 { 645 sal_uInt32 nFillColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()) ); 646 nFillBackColor = nFillColor ^ 0xffffff; 647 AddOpt( ESCHER_Prop_fillColor, nFillColor ); 648 } 649 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100010 ); 650 AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor ); 651 } 652 break; 653 } 654 case ::com::sun::star::drawing::FillStyle_NONE : 655 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 ); 656 break; 657 } 658 if ( eFS != ::com::sun::star::drawing::FillStyle_NONE ) 659 { 660 sal_uInt16 nTransparency = ( EscherPropertyValueHelper::GetPropertyValue( 661 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillTransparence" ) ), sal_True ) ) 662 ? *((sal_Int16*)aAny.getValue() ) 663 : 0; 664 if ( nTransparency ) 665 AddOpt( ESCHER_Prop_fillOpacity, ( ( 100 - nTransparency ) << 16 ) / 100 ); 666 } 667 } 668 CreateLineProperties( rXPropSet, bEdge ); 669 } 670 671 void EscherPropertyContainer::CreateTextProperties( 672 const uno::Reference< beans::XPropertySet > & rXPropSet, sal_uInt32 nTextId, 673 const sal_Bool bIsCustomShape, const sal_Bool bIsTextFrame ) 674 { 675 uno::Any aAny; 676 text::WritingMode eWM( text::WritingMode_LR_TB ); 677 drawing::TextVerticalAdjust eVA( drawing::TextVerticalAdjust_TOP ); 678 drawing::TextHorizontalAdjust eHA( drawing::TextHorizontalAdjust_LEFT ); 679 680 sal_Int32 nLeft ( 0 ); 681 sal_Int32 nTop ( 0 ); 682 sal_Int32 nRight ( 0 ); 683 sal_Int32 nBottom ( 0 ); 684 685 // used with normal shapes: 686 sal_Bool bAutoGrowWidth ( sal_False ); 687 sal_Bool bAutoGrowHeight ( sal_False ); 688 // used with ashapes: 689 sal_Bool bWordWrap ( sal_False ); 690 sal_Bool bAutoGrowSize ( sal_False ); 691 692 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextWritingMode" ) ), sal_True ) ) 693 aAny >>= eWM; 694 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextVerticalAdjust" ) ), sal_True ) ) 695 aAny >>= eVA; 696 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextHorizontalAdjust" ) ), sal_True ) ) 697 aAny >>= eHA; 698 if ( bIsCustomShape ) 699 { 700 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextWordWrap" ) ), sal_False ) ) 701 aAny >>= bWordWrap; 702 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True ) ) 703 aAny >>= bAutoGrowSize; 704 } 705 else if ( bIsTextFrame ) 706 { 707 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowWidth" ) ), sal_True ) ) 708 aAny >>= bAutoGrowWidth; 709 710 // i63936 not setting autogrowheight, because otherwise 711 // the minframeheight of the text will be ignored 712 // 713 // if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True ) ) 714 // aAny >>= bAutoGrowHeight; 715 } 716 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) ) ) ) 717 aAny >>= nLeft; 718 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) ) ) ) 719 aAny >>= nTop; 720 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) ) ) ) 721 aAny >>= nRight; 722 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) ) ) ) 723 aAny >>= nBottom; 724 725 /* 726 if ( rObj.ImplGetPropertyValue( 727 ::rtl::OUString::createFromAscii("TextWritingMode") ) ) 728 { 729 ::com::sun::star::text::WritingMode eMode; 730 rObj.GetUsrAny() >>= eMode; 731 switch (eMode) 732 { 733 case ::com::sun::star::text::WritingMode_TB_RL: 734 //Well if it so happens that we are fliped 180 we can use 735 //this instead. 736 if (rObj.GetAngle() == 18000) 737 eFlow = ESCHER_txflBtoT; 738 else 739 eFlow = ESCHER_txflTtoBA; 740 break; 741 case ::com::sun::star::text::WritingMode_RL_TB: 742 eDir = ESCHER_txdirRTL; 743 break; 744 } 745 } 746 */ 747 748 ESCHER_AnchorText eAnchor = ESCHER_AnchorTop; 749 ESCHER_WrapMode eWrapMode = ESCHER_WrapSquare; 750 sal_uInt32 nTextAttr = 0x40004; // rotate text with shape 751 752 if ( eWM == text::WritingMode_TB_RL ) 753 { // verical writing 754 switch ( eHA ) 755 { 756 case drawing::TextHorizontalAdjust_LEFT : 757 eAnchor = ESCHER_AnchorBottom; 758 break; 759 case drawing::TextHorizontalAdjust_CENTER : 760 eAnchor = ESCHER_AnchorMiddle; 761 break; 762 default : 763 case drawing::TextHorizontalAdjust_BLOCK : 764 case drawing::TextHorizontalAdjust_RIGHT : 765 eAnchor = ESCHER_AnchorTop; 766 break; 767 } 768 if ( eVA == drawing::TextVerticalAdjust_CENTER ) 769 { 770 switch ( eAnchor ) 771 { 772 case ESCHER_AnchorMiddle : 773 eAnchor = ESCHER_AnchorMiddleCentered; 774 break; 775 case ESCHER_AnchorBottom : 776 eAnchor = ESCHER_AnchorBottomCentered; 777 break; 778 default : 779 case ESCHER_AnchorTop : 780 eAnchor = ESCHER_AnchorTopCentered; 781 break; 782 } 783 } 784 if ( bIsCustomShape ) 785 { 786 if ( bWordWrap ) 787 eWrapMode = ESCHER_WrapSquare; 788 else 789 eWrapMode = ESCHER_WrapNone; 790 if ( bAutoGrowSize ) 791 nTextAttr |= 0x20002; 792 } 793 else 794 { 795 if ( bAutoGrowHeight ) 796 eWrapMode = ESCHER_WrapNone; 797 if ( bAutoGrowWidth ) 798 nTextAttr |= 0x20002; 799 } 800 801 AddOpt( ESCHER_Prop_txflTextFlow, ESCHER_txflTtoBA ); // rotate text within shape by 90 802 } 803 else 804 { // normal from left to right 805 switch ( eVA ) 806 { 807 case drawing::TextVerticalAdjust_CENTER : 808 eAnchor = ESCHER_AnchorMiddle; 809 break; 810 811 case drawing::TextVerticalAdjust_BOTTOM : 812 eAnchor = ESCHER_AnchorBottom; 813 break; 814 815 default : 816 case drawing::TextVerticalAdjust_TOP : 817 eAnchor = ESCHER_AnchorTop; 818 break; 819 } 820 if ( eHA == drawing::TextHorizontalAdjust_CENTER ) 821 { 822 switch( eAnchor ) 823 { 824 case ESCHER_AnchorMiddle : 825 eAnchor = ESCHER_AnchorMiddleCentered; 826 break; 827 case ESCHER_AnchorBottom : 828 eAnchor = ESCHER_AnchorBottomCentered; 829 break; 830 case ESCHER_AnchorTop : 831 eAnchor = ESCHER_AnchorTopCentered; 832 break; 833 default: break; 834 } 835 } 836 if ( bIsCustomShape ) 837 { 838 if ( bWordWrap ) 839 eWrapMode = ESCHER_WrapSquare; 840 else 841 eWrapMode = ESCHER_WrapNone; 842 if ( bAutoGrowSize ) 843 nTextAttr |= 0x20002; 844 } 845 else 846 { 847 if ( bAutoGrowWidth ) 848 eWrapMode = ESCHER_WrapNone; 849 if ( bAutoGrowHeight ) 850 nTextAttr |= 0x20002; 851 } 852 } 853 AddOpt( ESCHER_Prop_dxTextLeft, nLeft * 360 ); 854 AddOpt( ESCHER_Prop_dxTextRight, nRight * 360 ); 855 AddOpt( ESCHER_Prop_dyTextTop, nTop * 360 ); 856 AddOpt( ESCHER_Prop_dyTextBottom, nBottom * 360 ); 857 858 AddOpt( ESCHER_Prop_WrapText, eWrapMode ); 859 AddOpt( ESCHER_Prop_AnchorText, eAnchor ); 860 AddOpt( ESCHER_Prop_FitTextToShape, nTextAttr ); 861 862 if ( nTextId ) 863 AddOpt( ESCHER_Prop_lTxid, nTextId ); 864 } 865 866 sal_Bool EscherPropertyContainer::GetLineArrow( const sal_Bool bLineStart, 867 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 868 ESCHER_LineEnd& reLineEnd, sal_Int32& rnArrowLength, sal_Int32& rnArrowWidth ) 869 { 870 static String sLineStart ( RTL_CONSTASCII_USTRINGPARAM( "LineStart" ) ); 871 static String sLineStartName( RTL_CONSTASCII_USTRINGPARAM( "LineStartName" ) ); 872 static String sLineEnd ( RTL_CONSTASCII_USTRINGPARAM( "LineEnd" ) ); 873 static String sLineEndName ( RTL_CONSTASCII_USTRINGPARAM( "LineEndName" ) ); 874 875 const String sLine ( bLineStart ? sLineStart : sLineEnd ); 876 const String sLineName ( bLineStart ? sLineStartName : sLineEndName ); 877 878 sal_Bool bIsArrow = sal_False; 879 880 ::com::sun::star::uno::Any aAny; 881 if ( EscherPropertyValueHelper::GetPropertyValue( 882 aAny, rXPropSet, sLine, sal_False ) ) 883 { 884 PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aAny ) ); 885 if ( aPolyPoly.Count() && aPolyPoly[ 0 ].GetSize() ) 886 { 887 bIsArrow = sal_True; 888 889 reLineEnd = ESCHER_LineArrowEnd; 890 rnArrowLength = 1; 891 rnArrowWidth = 1; 892 893 if ( EscherPropertyValueHelper::GetPropertyValue( 894 aAny, rXPropSet, sLineName, sal_False ) ) 895 { 896 String aArrowStartName = *(::rtl::OUString*)aAny.getValue(); 897 rtl::OUString aApiName; 898 sal_Int16 nWhich = bLineStart ? XATTR_LINESTART : XATTR_LINEEND; 899 900 SvxUnogetApiNameForItem( nWhich, aArrowStartName, aApiName ); 901 sal_Bool bIsMapped = sal_True; 902 if ( aApiName.getLength() ) 903 { 904 905 /* todo: 906 calculate the best option for ArrowLenght and ArrowWidth 907 */ 908 if ( aApiName.equalsAscii( "Arrow concave" ) ) 909 reLineEnd = ESCHER_LineArrowStealthEnd; 910 else if ( aApiName.equalsAscii( "Square 45" ) ) 911 reLineEnd = ESCHER_LineArrowDiamondEnd; 912 else if ( aApiName.equalsAscii( "Small Arrow" ) ) 913 reLineEnd = ESCHER_LineArrowEnd; 914 else if ( aApiName.equalsAscii( "Dimension Lines" ) ) 915 { 916 rnArrowLength = 0; 917 rnArrowWidth = 2; 918 reLineEnd = ESCHER_LineArrowOvalEnd; 919 } 920 else if ( aApiName.equalsAscii( "Double Arrow" ) ) 921 reLineEnd = ESCHER_LineArrowEnd; 922 else if ( aApiName.equalsAscii( "Rounded short Arrow" ) ) 923 reLineEnd = ESCHER_LineArrowEnd; 924 else if ( aApiName.equalsAscii( "Symmetric Arrow" ) ) 925 reLineEnd = ESCHER_LineArrowEnd; 926 else if ( aApiName.equalsAscii( "Line Arrow" ) ) 927 reLineEnd = ESCHER_LineArrowOpenEnd; 928 else if ( aApiName.equalsAscii( "Rounded large Arrow" ) ) 929 reLineEnd = ESCHER_LineArrowEnd; 930 else if ( aApiName.equalsAscii( "Circle" ) ) 931 reLineEnd = ESCHER_LineArrowOvalEnd; 932 else if ( aApiName.equalsAscii( "Square" ) ) 933 reLineEnd = ESCHER_LineArrowDiamondEnd; 934 else if ( aApiName.equalsAscii( "Arrow" ) ) 935 reLineEnd = ESCHER_LineArrowEnd; 936 else 937 bIsMapped = sal_False; 938 939 } 940 if ( !bIsMapped && aArrowStartName.GetTokenCount( ' ' ) == 2 ) 941 { 942 sal_Bool b = sal_True; 943 String aArrowName( aArrowStartName.GetToken( 0, ' ' ) ); 944 if ( aArrowName.EqualsAscii( "msArrowEnd" ) ) 945 reLineEnd = ESCHER_LineArrowEnd; 946 else if ( aArrowName.EqualsAscii( "msArrowOpenEnd" ) ) 947 reLineEnd = ESCHER_LineArrowOpenEnd; 948 else if ( aArrowName.EqualsAscii( "msArrowStealthEnd" ) ) 949 reLineEnd = ESCHER_LineArrowStealthEnd; 950 else if ( aArrowName.EqualsAscii( "msArrowDiamondEnd" ) ) 951 reLineEnd = ESCHER_LineArrowDiamondEnd; 952 else if ( aArrowName.EqualsAscii( "msArrowOvalEnd" ) ) 953 reLineEnd = ESCHER_LineArrowOvalEnd; 954 else 955 b = sal_False; 956 957 // now we have the arrow, and try to determine the arrow size; 958 if ( b ) 959 { 960 String aArrowSize( aArrowStartName.GetToken( 1, ' ' ) ); 961 sal_Int32 nArrowSize = aArrowSize.ToInt32(); 962 rnArrowWidth = ( nArrowSize - 1 ) / 3; 963 rnArrowLength = nArrowSize - ( rnArrowWidth * 3 ) - 1; 964 } 965 } 966 } 967 } 968 } 969 return bIsArrow; 970 } 971 972 void EscherPropertyContainer::CreateLineProperties( 973 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 974 sal_Bool bEdge ) 975 { 976 ::com::sun::star::uno::Any aAny; 977 sal_uInt32 nLineFlags = 0x80008; 978 979 ESCHER_LineEnd eLineEnd; 980 sal_Int32 nArrowLength; 981 sal_Int32 nArrowWidth; 982 983 sal_Bool bSwapLineEnds = sal_False; 984 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CircleKind" ) ), sal_True ) ) 985 { 986 ::com::sun::star::drawing::CircleKind eCircleKind; 987 if ( aAny >>= eCircleKind ) 988 { 989 if ( eCircleKind == ::com::sun::star::drawing::CircleKind_ARC ) 990 bSwapLineEnds = sal_True; 991 } 992 } 993 if ( GetLineArrow( bSwapLineEnds ? sal_False : sal_True, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) ) 994 { 995 AddOpt( ESCHER_Prop_lineStartArrowLength, nArrowLength ); 996 AddOpt( ESCHER_Prop_lineStartArrowWidth, nArrowWidth ); 997 AddOpt( ESCHER_Prop_lineStartArrowhead, eLineEnd ); 998 nLineFlags |= 0x100010; 999 } 1000 if ( GetLineArrow( bSwapLineEnds ? sal_True : sal_False, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) ) 1001 { 1002 AddOpt( ESCHER_Prop_lineEndArrowLength, nArrowLength ); 1003 AddOpt( ESCHER_Prop_lineEndArrowWidth, nArrowWidth ); 1004 AddOpt( ESCHER_Prop_lineEndArrowhead, eLineEnd ); 1005 nLineFlags |= 0x100010; 1006 } 1007 1008 // support LineCaps 1009 if(EscherPropertyValueHelper::GetPropertyValue(aAny, rXPropSet, String(RTL_CONSTASCII_USTRINGPARAM("LineCap")), sal_False)) 1010 { 1011 ::com::sun::star::drawing::LineCap aLineCap(com::sun::star::drawing::LineCap_BUTT); 1012 1013 if(aAny >>= aLineCap) 1014 { 1015 switch (aLineCap) 1016 { 1017 default: /* com::sun::star::drawing::LineCap_BUTT */ 1018 { 1019 AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapFlat); 1020 break; 1021 } 1022 case com::sun::star::drawing::LineCap_ROUND: 1023 { 1024 AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapRound); 1025 break; 1026 } 1027 case com::sun::star::drawing::LineCap_SQUARE: 1028 { 1029 AddOpt(ESCHER_Prop_lineEndCapStyle, ESCHER_LineEndCapSquare); 1030 break; 1031 } 1032 } 1033 } 1034 } 1035 1036 if ( EscherPropertyValueHelper::GetPropertyValue( 1037 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineStyle" ) ), sal_False ) ) 1038 { 1039 ::com::sun::star::drawing::LineStyle eLS; 1040 if ( aAny >>= eLS ) 1041 { 1042 switch ( eLS ) 1043 { 1044 case ::com::sun::star::drawing::LineStyle_NONE : 1045 AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 ); // 80000 1046 break; 1047 1048 case ::com::sun::star::drawing::LineStyle_DASH : 1049 { 1050 if ( EscherPropertyValueHelper::GetPropertyValue( 1051 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineDash" ) ), sal_False ) ) 1052 { 1053 ESCHER_LineDashing eDash = ESCHER_LineSolid; 1054 ::com::sun::star::drawing::LineDash* pLineDash = (::com::sun::star::drawing::LineDash*)aAny.getValue(); 1055 sal_Int32 nDistance = pLineDash->Distance << 1; 1056 switch ( pLineDash->Style ) 1057 { 1058 case ::com::sun::star::drawing::DashStyle_ROUND : 1059 case ::com::sun::star::drawing::DashStyle_ROUNDRELATIVE : 1060 AddOpt( ESCHER_Prop_lineEndCapStyle, 0 ); // Style Round setzen 1061 break; 1062 default : break; 1063 } 1064 if ( ((!(pLineDash->Dots )) || (!(pLineDash->Dashes )) ) || ( pLineDash->DotLen == pLineDash->DashLen ) ) 1065 { 1066 sal_Int32 nLen = pLineDash->DotLen; 1067 if ( pLineDash->Dashes ) 1068 nLen = pLineDash->DashLen; 1069 1070 if ( nLen >= nDistance ) 1071 eDash = ESCHER_LineLongDashGEL; 1072 else if ( pLineDash->Dots ) 1073 eDash = ESCHER_LineDotSys; 1074 else 1075 eDash = ESCHER_LineDashGEL; 1076 } 1077 else // X Y 1078 { 1079 if ( pLineDash->Dots != pLineDash->Dashes ) 1080 { 1081 if ( ( pLineDash->DashLen > nDistance ) || ( pLineDash->DotLen > nDistance ) ) 1082 eDash = ESCHER_LineLongDashDotDotGEL; 1083 else 1084 eDash = ESCHER_LineDashDotDotSys; 1085 } 1086 else // X Y Y 1087 { 1088 if ( ( pLineDash->DashLen > nDistance ) || ( pLineDash->DotLen > nDistance ) ) 1089 eDash = ESCHER_LineLongDashDotGEL; 1090 else 1091 eDash = ESCHER_LineDashDotGEL; 1092 1093 } 1094 } 1095 AddOpt( ESCHER_Prop_lineDashing, eDash ); 1096 } 1097 } 1098 case ::com::sun::star::drawing::LineStyle_SOLID : 1099 default: 1100 { 1101 AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ); 1102 } 1103 break; 1104 } 1105 } 1106 if ( EscherPropertyValueHelper::GetPropertyValue( 1107 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineColor" ) ), sal_False ) ) 1108 { 1109 sal_uInt32 nLineColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()) ); 1110 AddOpt( ESCHER_Prop_lineColor, nLineColor ); 1111 AddOpt( ESCHER_Prop_lineBackColor, nLineColor ^ 0xffffff ); 1112 } 1113 } 1114 1115 sal_uInt32 nLineSize = ( EscherPropertyValueHelper::GetPropertyValue( 1116 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineWidth" ) ), sal_False ) ) 1117 ? *((sal_uInt32*)aAny.getValue()) 1118 : 0; 1119 if ( nLineSize > 1 ) 1120 AddOpt( ESCHER_Prop_lineWidth, nLineSize * 360 ); // 100TH MM -> PT , 1PT = 12700 EMU 1121 1122 ESCHER_LineJoin eLineJoin = ESCHER_LineJoinMiter; 1123 if ( EscherPropertyValueHelper::GetPropertyValue( 1124 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineJoint" ) ), sal_True ) ) 1125 { 1126 ::com::sun::star::drawing::LineJoint eLJ; 1127 if ( aAny >>= eLJ ) 1128 { 1129 switch ( eLJ ) 1130 { 1131 case com::sun::star::drawing::LineJoint_NONE : 1132 case com::sun::star::drawing::LineJoint_MIDDLE : 1133 case com::sun::star::drawing::LineJoint_BEVEL : 1134 eLineJoin = ESCHER_LineJoinBevel; 1135 break; 1136 default: 1137 case com::sun::star::drawing::LineJoint_MITER : 1138 eLineJoin = ESCHER_LineJoinMiter; 1139 break; 1140 case com::sun::star::drawing::LineJoint_ROUND : 1141 eLineJoin = ESCHER_LineJoinRound; 1142 break; 1143 } 1144 } 1145 } 1146 AddOpt( ESCHER_Prop_lineJoinStyle, eLineJoin ); 1147 1148 if ( EscherPropertyValueHelper::GetPropertyValue( 1149 aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineTransparence" ) ), sal_True ) ) 1150 { 1151 sal_Int16 nTransparency = 0; 1152 if ( aAny >>= nTransparency ) 1153 AddOpt( ESCHER_Prop_lineOpacity, ( ( 100 - nTransparency ) << 16 ) / 100 ); 1154 } 1155 1156 1157 if ( bEdge == sal_False ) 1158 { 1159 AddOpt( ESCHER_Prop_fFillOK, 0x1001 ); 1160 AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 ); 1161 } 1162 } 1163 1164 static Size lcl_SizeToEmu(Size aPrefSize, MapMode aPrefMapMode) 1165 { 1166 Size aRetSize; 1167 if (aPrefMapMode == MAP_PIXEL) 1168 aRetSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM ); 1169 else 1170 aRetSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM ); 1171 return aRetSize; 1172 } 1173 1174 void EscherPropertyContainer::ImplCreateGraphicAttributes( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 1175 sal_uInt32 nBlibId, sal_Bool bCreateCroppingAttributes ) 1176 { 1177 ::com::sun::star::uno::Any aAny; 1178 1179 sal_uInt32 nPicFlags = 0; 1180 ::com::sun::star::drawing::ColorMode eColorMode( ::com::sun::star::drawing::ColorMode_STANDARD ); 1181 sal_Int16 nLuminance = 0; 1182 sal_Int32 nContrast = 0; 1183 sal_Int16 nRed = 0; 1184 sal_Int16 nGreen = 0; 1185 sal_Int16 nBlue = 0; 1186 double fGamma = 1.0; 1187 sal_Int16 nTransparency = 0; 1188 1189 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicColorMode" ) ) ) ) 1190 aAny >>= eColorMode; 1191 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustLuminance" ) ) ) ) 1192 aAny >>= nLuminance; 1193 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustContrast" ) ) ) ) 1194 { 1195 sal_Int16 nC = sal_Int16(); 1196 aAny >>= nC; 1197 nContrast = nC; 1198 } 1199 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustRed" ) ) ) ) 1200 aAny >>= nRed; 1201 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustGreen" ) ) ) ) 1202 aAny >>= nGreen; 1203 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustBlue" ) ) ) ) 1204 aAny >>= nBlue; 1205 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Gamma" ) ) ) ) 1206 aAny >>= fGamma; 1207 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Transparency" ) ) ) ) 1208 aAny >>= nTransparency; 1209 1210 if ( eColorMode == ::com::sun::star::drawing::ColorMode_WATERMARK ) 1211 { 1212 eColorMode = ::com::sun::star::drawing::ColorMode_STANDARD; 1213 nLuminance += 70; 1214 if ( nLuminance > 100 ) 1215 nLuminance = 100; 1216 nContrast -= 70; 1217 if ( nContrast < -100 ) 1218 nContrast = -100; 1219 } 1220 if ( eColorMode == ::com::sun::star::drawing::ColorMode_GREYS ) 1221 nPicFlags |= 0x40004; 1222 else if ( eColorMode == ::com::sun::star::drawing::ColorMode_MONO ) 1223 nPicFlags |= 0x60006; 1224 1225 if ( nContrast ) 1226 { 1227 nContrast += 100; 1228 if ( nContrast == 100) 1229 nContrast = 0x10000; 1230 else if ( nContrast < 100 ) 1231 { 1232 nContrast *= 0x10000; 1233 nContrast /= 100; 1234 } 1235 else if ( nContrast < 200 ) 1236 nContrast = ( 100 * 0x10000 ) / ( 200 - nContrast ); 1237 else 1238 nContrast = 0x7fffffff; 1239 AddOpt( ESCHER_Prop_pictureContrast, nContrast ); 1240 } 1241 if ( nLuminance ) 1242 AddOpt( ESCHER_Prop_pictureBrightness, nLuminance * 327 ); 1243 if ( nPicFlags ) 1244 AddOpt( ESCHER_Prop_pictureActive, nPicFlags ); 1245 1246 if ( bCreateCroppingAttributes && pGraphicProvider ) 1247 { 1248 Size aPrefSize; 1249 MapMode aPrefMapMode; 1250 if ( pGraphicProvider->GetPrefSize( nBlibId, aPrefSize, aPrefMapMode ) ) 1251 { 1252 Size aCropSize(lcl_SizeToEmu(aPrefSize, aPrefMapMode)); 1253 if ( aCropSize.Width() && aCropSize.Height() ) 1254 { 1255 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicCrop" ) ) ) ) 1256 { 1257 ::com::sun::star::text::GraphicCrop aGraphCrop; 1258 if ( aAny >>= aGraphCrop ) 1259 { 1260 if ( aGraphCrop.Left ) 1261 { 1262 sal_uInt32 nLeft = ( aGraphCrop.Left * 65536 ) / aCropSize.Width(); 1263 AddOpt( ESCHER_Prop_cropFromLeft, nLeft ); 1264 } 1265 if ( aGraphCrop.Top ) 1266 { 1267 sal_uInt32 nTop = ( aGraphCrop.Top * 65536 ) / aCropSize.Height(); 1268 AddOpt( ESCHER_Prop_cropFromTop, nTop ); 1269 } 1270 if ( aGraphCrop.Right ) 1271 { 1272 sal_uInt32 nRight = ( aGraphCrop.Right * 65536 ) / aCropSize.Width(); 1273 AddOpt( ESCHER_Prop_cropFromRight, nRight ); 1274 } 1275 if ( aGraphCrop.Bottom ) 1276 { 1277 sal_uInt32 nBottom = ( aGraphCrop.Bottom * 65536 ) / aCropSize.Height(); 1278 AddOpt( ESCHER_Prop_cropFromBottom, nBottom ); 1279 } 1280 } 1281 } 1282 } 1283 } 1284 } 1285 } 1286 1287 sal_Bool EscherPropertyContainer::CreateShapeProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) 1288 { 1289 uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY ); 1290 if ( aXPropSet.is() ) 1291 { 1292 sal_Bool bVal = false; 1293 ::com::sun::star::uno::Any aAny; 1294 sal_uInt32 nShapeAttr = 0; 1295 EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ), sal_True ); 1296 if ( aAny >>= bVal ) 1297 { 1298 if ( !bVal ) 1299 nShapeAttr |= 0x20002; // set fHidden = true 1300 } 1301 EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) ), sal_True ); 1302 if ( aAny >>= bVal ) 1303 { 1304 if ( !bVal ) 1305 nShapeAttr |= 0x10000; // set fPrint = false; 1306 } 1307 if ( nShapeAttr ) 1308 AddOpt( ESCHER_Prop_fPrint, nShapeAttr ); 1309 } 1310 return sal_True; 1311 } 1312 1313 sal_Bool EscherPropertyContainer::CreateOLEGraphicProperties( 1314 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) 1315 { 1316 sal_Bool bRetValue = sal_False; 1317 1318 if ( rXShape.is() ) 1319 { 1320 SdrObject* pSdrOLE2( GetSdrObjectFromXShape( rXShape ) ); // SJ: leaving unoapi, because currently there is 1321 if ( pSdrOLE2 && pSdrOLE2->ISA( SdrOle2Obj ) ) // no access to the native graphic object 1322 { 1323 Graphic* pGraphic = ((SdrOle2Obj*)pSdrOLE2)->GetGraphic(); 1324 if ( pGraphic ) 1325 { 1326 GraphicObject aGraphicObject( *pGraphic ); 1327 bRetValue = CreateGraphicProperties( rXShape,aGraphicObject ); 1328 // End 1329 } 1330 } 1331 } 1332 return bRetValue; 1333 } 1334 1335 sal_Bool EscherPropertyContainer::CreateGraphicProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ,const GraphicObject& rGraphicObj ) 1336 { 1337 sal_Bool bRetValue = sal_False; 1338 ByteString aUniqueId( rGraphicObj.GetUniqueID() ); 1339 if ( aUniqueId.Len() ) 1340 { 1341 AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture ); 1342 uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY ); 1343 1344 if ( pGraphicProvider && pPicOutStrm && pShapeBoundRect && aXPropSet.is() ) 1345 { 1346 ::com::sun::star::uno::Any aAny; 1347 ::com::sun::star::awt::Rectangle* pVisArea = NULL; 1348 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) ) ) ) 1349 { 1350 pVisArea = new ::com::sun::star::awt::Rectangle; 1351 aAny >>= (*pVisArea); 1352 } 1353 Rectangle aRect( Point( 0, 0 ), pShapeBoundRect->GetSize() ); 1354 sal_uInt32 nBlibId = pGraphicProvider->GetBlibID( *pPicOutStrm, aUniqueId, aRect, pVisArea, NULL ); 1355 if ( nBlibId ) 1356 { 1357 AddOpt( ESCHER_Prop_pib, nBlibId, sal_True ); 1358 ImplCreateGraphicAttributes( aXPropSet, nBlibId, sal_False ); 1359 bRetValue = sal_True; 1360 } 1361 delete pVisArea; 1362 } 1363 } 1364 return bRetValue; 1365 } 1366 1367 sal_Bool EscherPropertyContainer::CreateMediaGraphicProperties( 1368 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) 1369 { 1370 sal_Bool bRetValue = sal_False; 1371 if ( rXShape.is() ) 1372 { 1373 SdrObject* pSdrMedia( GetSdrObjectFromXShape( rXShape ) ); // SJ: leaving unoapi, because currently there is 1374 if ( pSdrMedia && pSdrMedia->ISA( SdrMediaObj ) ) // no access to the native graphic object 1375 { 1376 GraphicObject aGraphicObject( ((SdrMediaObj*)pSdrMedia)->getGraphic() ); 1377 bRetValue = CreateGraphicProperties( rXShape, aGraphicObject ); 1378 } 1379 } 1380 return bRetValue; 1381 } 1382 1383 sal_Bool EscherPropertyContainer::ImplCreateEmbeddedBmp( const ByteString& rUniqueId ) 1384 { 1385 if( rUniqueId.Len() > 0 ) 1386 { 1387 EscherGraphicProvider aProvider; 1388 SvMemoryStream aMemStrm; 1389 Rectangle aRect; 1390 if ( aProvider.GetBlibID( aMemStrm, rUniqueId, aRect ) ) 1391 { 1392 // grab BLIP from stream and insert directly as complex property 1393 // ownership of stream memory goes to complex property 1394 aMemStrm.ObjectOwnsMemory( sal_False ); 1395 sal_uInt8* pBuf = (sal_uInt8*) aMemStrm.GetData(); 1396 sal_uInt32 nSize = aMemStrm.Seek( STREAM_SEEK_TO_END ); 1397 AddOpt( ESCHER_Prop_fillBlip, sal_True, nSize, pBuf, nSize ); 1398 return sal_True; 1399 } 1400 } 1401 return sal_False; 1402 } 1403 1404 sal_Bool EscherPropertyContainer::CreateEmbeddedBitmapProperties( 1405 const ::rtl::OUString& rBitmapUrl, ::com::sun::star::drawing::BitmapMode eBitmapMode ) 1406 { 1407 sal_Bool bRetValue = sal_False; 1408 String aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) ); 1409 String aBmpUrl( rBitmapUrl ); 1410 xub_StrLen nIndex = aBmpUrl.Search( aVndUrl, 0 ); 1411 if( nIndex != STRING_NOTFOUND ) 1412 { 1413 // note: += ist not defined for xub_StrLen -> conversion to int and back to xub_StrLen 1414 nIndex = nIndex + aVndUrl.Len(); 1415 if( aBmpUrl.Len() > nIndex ) 1416 { 1417 ByteString aUniqueId( aBmpUrl, nIndex, aBmpUrl.Len() - nIndex, RTL_TEXTENCODING_UTF8 ); 1418 bRetValue = ImplCreateEmbeddedBmp( aUniqueId ); 1419 if( bRetValue ) 1420 { 1421 // bitmap mode property 1422 bool bRepeat = eBitmapMode == ::com::sun::star::drawing::BitmapMode_REPEAT; 1423 AddOpt( ESCHER_Prop_fillType, bRepeat ? ESCHER_FillTexture : ESCHER_FillPicture ); 1424 } 1425 } 1426 } 1427 return bRetValue; 1428 } 1429 1430 1431 namespace { 1432 1433 GraphicObject lclDrawHatch( const ::com::sun::star::drawing::Hatch& rHatch, const Color& rBackColor, bool bFillBackground ) 1434 { 1435 const MapMode aMap100( MAP_100TH_MM ); 1436 VirtualDevice aVDev( *Application::GetDefaultDevice(), 0, 1 ); 1437 aVDev.SetMapMode( aMap100 ); 1438 1439 const Size aOutSize = aVDev.PixelToLogic( Size( 28, 28 ) ); 1440 aVDev.SetOutputSize( aOutSize ); 1441 1442 Rectangle aRectangle( Point( 0, 0 ), aOutSize ); 1443 const PolyPolygon aPolyPoly( aRectangle ); 1444 1445 aVDev.SetLineColor(); 1446 aVDev.SetFillColor( bFillBackground ? rBackColor : Color( COL_TRANSPARENT ) ); 1447 aVDev.DrawRect( Rectangle( Point(), aOutSize ) ); 1448 1449 Hatch aVclHatch( (HatchStyle) rHatch.Style, Color( rHatch.Color ), rHatch.Distance, (sal_uInt16)rHatch.Angle ); 1450 aVDev.DrawHatch( aPolyPoly, aVclHatch ); 1451 1452 return GraphicObject( Graphic( aVDev.GetBitmapEx( Point(), aOutSize ) ) ); 1453 } 1454 1455 } // namespace 1456 1457 1458 sal_Bool EscherPropertyContainer::CreateEmbeddedHatchProperties( const ::com::sun::star::drawing::Hatch& rHatch, const Color& rBackColor, bool bFillBackground ) 1459 { 1460 GraphicObject aGraphicObject = lclDrawHatch( rHatch, rBackColor, bFillBackground ); 1461 ByteString aUniqueId = aGraphicObject.GetUniqueID(); 1462 sal_Bool bRetValue = ImplCreateEmbeddedBmp( aUniqueId ); 1463 if ( bRetValue ) 1464 AddOpt( ESCHER_Prop_fillType, ESCHER_FillTexture ); 1465 return bRetValue; 1466 } 1467 1468 1469 sal_Bool EscherPropertyContainer::CreateGraphicProperties( 1470 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 1471 const String& rSource, const sal_Bool bCreateFillBitmap, const sal_Bool bCreateCroppingAttributes, 1472 const sal_Bool bFillBitmapModeAllowed ) 1473 { 1474 sal_Bool bRetValue = sal_False; 1475 sal_Bool bCreateFillStyles = sal_False; 1476 1477 sal_Bool bMirrored = sal_False; 1478 sal_Bool bRotate = sal_True; 1479 sal_uInt16 nAngle = 0; 1480 GraphicAttr* pGraphicAttr = NULL; 1481 GraphicObject aGraphicObject; 1482 String aGraphicUrl; 1483 ByteString aUniqueId; 1484 bool bIsGraphicMtf(false); 1485 1486 ::com::sun::star::drawing::BitmapMode eBitmapMode( ::com::sun::star::drawing::BitmapMode_NO_REPEAT ); 1487 ::com::sun::star::uno::Any aAny; 1488 1489 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, rSource ) ) 1490 { 1491 if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ) ) 1492 { 1493 ::com::sun::star::uno::Sequence<sal_uInt8> aSeq = *(::com::sun::star::uno::Sequence<sal_uInt8>*)aAny.getValue(); 1494 const sal_uInt8* pAry = aSeq.getArray(); 1495 sal_uInt32 nAryLen = aSeq.getLength(); 1496 1497 // the metafile is already rotated 1498 bRotate = sal_False; 1499 1500 if ( pAry && nAryLen ) 1501 { 1502 Graphic aGraphic; 1503 SvMemoryStream aTemp( (void*)pAry, nAryLen, STREAM_READ ); 1504 sal_uInt32 nErrCode = GraphicConverter::Import( aTemp, aGraphic, CVT_WMF ); 1505 if ( nErrCode == ERRCODE_NONE ) 1506 { 1507 aGraphicObject = aGraphic; 1508 aUniqueId = aGraphicObject.GetUniqueID(); 1509 bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE; 1510 } 1511 } 1512 } 1513 else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ) ) 1514 { 1515 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap >xBitmap; 1516 if ( ::cppu::extractInterface( xBitmap, aAny ) ) 1517 { 1518 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp; 1519 if ( aAny >>= xBmp ) 1520 { 1521 BitmapEx aBitmapEx( VCLUnoHelper::GetBitmap( xBmp ) ); 1522 Graphic aGraphic( aBitmapEx ); 1523 aGraphicObject = aGraphic; 1524 aUniqueId = aGraphicObject.GetUniqueID(); 1525 bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE; 1526 } 1527 } 1528 } 1529 else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ) ) 1530 { 1531 aGraphicUrl = *(::rtl::OUString*)aAny.getValue(); 1532 } 1533 else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ) ) 1534 { 1535 aGraphicUrl = *(::rtl::OUString*)aAny.getValue(); 1536 bCreateFillStyles = sal_True; 1537 } 1538 else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ) ) 1539 { 1540 ::com::sun::star::drawing::Hatch aHatch; 1541 if ( aAny >>= aHatch ) 1542 { 1543 Color aBackColor; 1544 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1545 String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False ) ) 1546 { 1547 aBackColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()), sal_False ); 1548 } 1549 bool bFillBackground = false; 1550 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1551 String( RTL_CONSTASCII_USTRINGPARAM( "FillBackground" ) ), sal_True ) ) 1552 { 1553 aAny >>= bFillBackground; 1554 } 1555 aGraphicObject = lclDrawHatch( aHatch, aBackColor, bFillBackground ); 1556 aUniqueId = aGraphicObject.GetUniqueID(); 1557 eBitmapMode = ::com::sun::star::drawing::BitmapMode_REPEAT; 1558 bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE; 1559 } 1560 } 1561 1562 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsMirrored" ) ), sal_True ) ) 1563 aAny >>= bMirrored; 1564 1565 if ( bCreateFillBitmap && bFillBitmapModeAllowed ) 1566 { 1567 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapMode" ) ), sal_True ) ) 1568 aAny >>= eBitmapMode; 1569 } 1570 else 1571 { 1572 nAngle = bRotate && EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1573 String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) 1574 ? (sal_uInt16)( ( *((sal_Int32*)aAny.getValue() ) ) + 5 ) / 10 1575 : 0; 1576 } 1577 1578 if ( aGraphicUrl.Len() ) 1579 { 1580 String aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) ); 1581 xub_StrLen nIndex = aGraphicUrl.Search( aVndUrl, 0 ); 1582 if ( nIndex != STRING_NOTFOUND ) 1583 { 1584 nIndex = nIndex + aVndUrl.Len(); 1585 if ( aGraphicUrl.Len() > nIndex ) 1586 aUniqueId = ByteString( aGraphicUrl, nIndex, aGraphicUrl.Len() - nIndex, RTL_TEXTENCODING_UTF8 ); 1587 } 1588 else 1589 { 1590 // externally, linked graphic? convert to embedded 1591 // one, if transformations are needed. this is because 1592 // everything < msoxp cannot even handle rotated 1593 // bitmaps. 1594 // And check whether the graphic link target is 1595 // actually supported by mso. 1596 INetURLObject aTmp( aGraphicUrl ); 1597 GraphicDescriptor aDescriptor(aTmp); 1598 aDescriptor.Detect(); 1599 const sal_uInt16 nFormat = aDescriptor.GetFileFormat(); 1600 1601 // can MSO handle it? 1602 if ( bMirrored || nAngle || 1603 (nFormat != GFF_BMP && 1604 nFormat != GFF_GIF && 1605 nFormat != GFF_JPG && 1606 nFormat != GFF_PNG && 1607 nFormat != GFF_TIF && 1608 nFormat != GFF_PCT && 1609 nFormat != GFF_WMF && 1610 nFormat != GFF_EMF) ) 1611 { 1612 SvStream* pIn = ::utl::UcbStreamHelper::CreateStream( 1613 aTmp.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ); 1614 if ( pIn ) 1615 { 1616 Graphic aGraphic; 1617 sal_uInt32 nErrCode = GraphicConverter::Import( *pIn, aGraphic ); 1618 1619 if ( nErrCode == ERRCODE_NONE ) 1620 { 1621 // no. 1622 aGraphicObject = aGraphic; 1623 aUniqueId = aGraphicObject.GetUniqueID(); 1624 } 1625 // else: simply keep the graphic link 1626 delete pIn; 1627 } 1628 } 1629 if ( !aUniqueId.Len() ) 1630 { 1631 if ( pGraphicProvider ) 1632 { 1633 const rtl::OUString& rBaseURI( pGraphicProvider->GetBaseURI() ); 1634 INetURLObject aBaseURI( rBaseURI ); 1635 if( aBaseURI.GetProtocol() == aTmp.GetProtocol() ) 1636 { 1637 rtl::OUString aRelUrl( INetURLObject::GetRelURL( rBaseURI, aGraphicUrl, 1638 INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI, RTL_TEXTENCODING_UTF8, INetURLObject::FSYS_DETECT ) ); 1639 if ( aRelUrl.getLength() ) 1640 aGraphicUrl = aRelUrl; 1641 } 1642 } 1643 } 1644 } 1645 } 1646 1647 if ( aGraphicUrl.Len() || aUniqueId.Len() ) 1648 { 1649 if ( bMirrored || nAngle ) 1650 { 1651 pGraphicAttr = new GraphicAttr; 1652 if ( bMirrored ) 1653 pGraphicAttr->SetMirrorFlags( BMP_MIRROR_HORZ ); 1654 if ( bIsGraphicMtf ) 1655 AddOpt( ESCHER_Prop_Rotation, ( ( ((sal_Int32)nAngle << 16 ) / 10 ) + 0x8000 ) &~ 0xffff ); 1656 } 1657 1658 if ( eBitmapMode == ::com::sun::star::drawing::BitmapMode_REPEAT ) 1659 { 1660 sal_Int32 nSizeX = 0,nSizeY = 0,nOffsetX = 0,nOffsetY = 0,nPosOffsetX = 0,nPosOffsetY = 0; 1661 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1662 String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapSizeX" ) ), sal_True ) ) 1663 { 1664 aAny >>= nSizeX; 1665 } 1666 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1667 String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapSizeY" ) ), sal_True ) ) 1668 { 1669 aAny >>= nSizeY; 1670 } 1671 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1672 String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapOffsetX" ) ), sal_True ) ) 1673 { 1674 aAny >>= nOffsetX; 1675 } 1676 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1677 String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapOffsetY" ) ), sal_True ) ) 1678 { 1679 aAny >>= nOffsetY; 1680 } 1681 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1682 String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapPositionOffsetX" ) ), sal_True ) ) 1683 { 1684 aAny >>= nPosOffsetX; 1685 } 1686 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1687 String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapPositionOffsetY" ) ), sal_True ) ) 1688 { 1689 aAny >>= nPosOffsetY; 1690 } 1691 if(nSizeX == -100 && nSizeY == -100 && nOffsetX == 0 && nOffsetY == 0 && nPosOffsetX == 0 && nPosOffsetY == 0) 1692 AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture ); 1693 else 1694 AddOpt( ESCHER_Prop_fillType, ESCHER_FillTexture ); 1695 } 1696 else 1697 AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture ); 1698 1699 if ( aUniqueId.Len() ) 1700 { 1701 // write out embedded graphic 1702 if ( pGraphicProvider && pPicOutStrm && pShapeBoundRect ) 1703 { 1704 Rectangle aRect( Point( 0, 0 ), pShapeBoundRect->GetSize() ); 1705 1706 sal_uInt32 nBlibId = 0; 1707 nBlibId = pGraphicProvider->GetBlibID( *pPicOutStrm, aUniqueId, aRect, NULL, pGraphicAttr ); 1708 if ( nBlibId ) 1709 { 1710 if ( bCreateFillBitmap ) 1711 AddOpt( ESCHER_Prop_fillBlip, nBlibId, sal_True ); 1712 else 1713 { 1714 AddOpt( ESCHER_Prop_pib, nBlibId, sal_True ); 1715 ImplCreateGraphicAttributes( rXPropSet, nBlibId, bCreateCroppingAttributes ); 1716 } 1717 bRetValue = sal_True; 1718 } 1719 } 1720 else 1721 { 1722 EscherGraphicProvider aProvider; 1723 SvMemoryStream aMemStrm; 1724 Rectangle aRect; 1725 1726 if ( aProvider.GetBlibID( aMemStrm, aUniqueId, aRect, NULL, pGraphicAttr ) ) 1727 { 1728 // grab BLIP from stream and insert directly as complex property 1729 // ownership of stream memory goes to complex property 1730 aMemStrm.ObjectOwnsMemory( sal_False ); 1731 sal_uInt8* pBuf = (sal_uInt8*) aMemStrm.GetData(); 1732 sal_uInt32 nSize = aMemStrm.Seek( STREAM_SEEK_TO_END ); 1733 AddOpt( ESCHER_Prop_fillBlip, sal_True, nSize, pBuf, nSize ); 1734 bRetValue = sal_True; 1735 } 1736 } 1737 } 1738 // write out link to graphic 1739 else 1740 { 1741 OSL_ASSERT(aGraphicUrl.Len()); 1742 1743 AddOpt( ESCHER_Prop_pibName, aGraphicUrl ); 1744 sal_uInt32 nPibFlags=0; 1745 GetOpt( ESCHER_Prop_pibFlags, nPibFlags ); 1746 AddOpt( ESCHER_Prop_pibFlags, 1747 ESCHER_BlipFlagLinkToFile|ESCHER_BlipFlagFile|ESCHER_BlipFlagDoNotSave | nPibFlags ); 1748 } 1749 } 1750 } 1751 delete pGraphicAttr; 1752 if ( bCreateFillStyles ) 1753 CreateFillProperties( rXPropSet, sal_True ); 1754 1755 return bRetValue; 1756 } 1757 1758 PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) 1759 { 1760 PolyPolygon aRetPolyPoly; 1761 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXPropSet; 1762 ::com::sun::star::uno::Any aAny( rXShape->queryInterface( 1763 ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) )); 1764 1765 String sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) ); 1766 String sPolyPolygon ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) ); 1767 String sPolygon ( RTL_CONSTASCII_USTRINGPARAM( "Polygon" ) ); 1768 1769 if ( aAny >>= aXPropSet ) 1770 { 1771 sal_Bool bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolyPolygonBezier, sal_True ); 1772 if ( !bHasProperty ) 1773 bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolyPolygon, sal_True ); 1774 if ( !bHasProperty ) 1775 bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolygon, sal_True ); 1776 if ( bHasProperty ) 1777 aRetPolyPoly = GetPolyPolygon( aAny ); 1778 } 1779 return aRetPolyPoly; 1780 } 1781 1782 PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Any& rAny ) 1783 { 1784 sal_Bool bNoError = sal_True; 1785 1786 Polygon aPolygon; 1787 PolyPolygon aPolyPolygon; 1788 1789 if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PolyPolygonBezierCoords* ) 0 ) ) 1790 { 1791 ::com::sun::star::drawing::PolyPolygonBezierCoords* pSourcePolyPolygon 1792 = (::com::sun::star::drawing::PolyPolygonBezierCoords*)rAny.getValue(); 1793 sal_uInt16 nOuterSequenceCount = (sal_uInt16)pSourcePolyPolygon->Coordinates.getLength(); 1794 1795 // Zeiger auf innere sequences holen 1796 ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray(); 1797 ::com::sun::star::drawing::FlagSequence* pOuterFlags = pSourcePolyPolygon->Flags.getArray(); 1798 1799 bNoError = pOuterSequence && pOuterFlags; 1800 if ( bNoError ) 1801 { 1802 sal_uInt16 a, b, nInnerSequenceCount; 1803 ::com::sun::star::awt::Point* pArray; 1804 1805 // dies wird ein Polygon set 1806 for ( a = 0; a < nOuterSequenceCount; a++ ) 1807 { 1808 ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++; 1809 ::com::sun::star::drawing::FlagSequence* pInnerFlags = pOuterFlags++; 1810 1811 bNoError = pInnerSequence && pInnerFlags; 1812 if ( bNoError ) 1813 { 1814 // Zeiger auf Arrays holen 1815 pArray = pInnerSequence->getArray(); 1816 ::com::sun::star::drawing::PolygonFlags* pFlags = pInnerFlags->getArray(); 1817 1818 if ( pArray && pFlags ) 1819 { 1820 nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength(); 1821 aPolygon = Polygon( nInnerSequenceCount ); 1822 for( b = 0; b < nInnerSequenceCount; b++) 1823 { 1824 PolyFlags ePolyFlags( *( (PolyFlags*)pFlags++ ) ); 1825 ::com::sun::star::awt::Point aPoint( (::com::sun::star::awt::Point)*(pArray++) ); 1826 aPolygon[ b ] = Point( aPoint.X, aPoint.Y ); 1827 aPolygon.SetFlags( b, ePolyFlags ); 1828 1829 if ( ePolyFlags == POLY_CONTROL ) 1830 continue; 1831 } 1832 aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND ); 1833 } 1834 } 1835 } 1836 } 1837 } 1838 else if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequenceSequence* ) 0 ) ) 1839 { 1840 ::com::sun::star::drawing::PointSequenceSequence* pSourcePolyPolygon 1841 = (::com::sun::star::drawing::PointSequenceSequence*)rAny.getValue(); 1842 sal_uInt16 nOuterSequenceCount = (sal_uInt16)pSourcePolyPolygon->getLength(); 1843 1844 // Zeiger auf innere sequences holen 1845 ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray(); 1846 bNoError = pOuterSequence != NULL; 1847 if ( bNoError ) 1848 { 1849 sal_uInt16 a, b, nInnerSequenceCount; 1850 1851 // dies wird ein Polygon set 1852 for( a = 0; a < nOuterSequenceCount; a++ ) 1853 { 1854 ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++; 1855 bNoError = pInnerSequence != NULL; 1856 if ( bNoError ) 1857 { 1858 // Zeiger auf Arrays holen 1859 ::com::sun::star::awt::Point* pArray = 1860 pInnerSequence->getArray(); 1861 if ( pArray != NULL ) 1862 { 1863 nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength(); 1864 aPolygon = Polygon( nInnerSequenceCount ); 1865 for( b = 0; b < nInnerSequenceCount; b++) 1866 { 1867 aPolygon[ b ] = Point( pArray->X, pArray->Y ); 1868 pArray++; 1869 } 1870 aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND ); 1871 } 1872 } 1873 } 1874 } 1875 } 1876 else if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequence* ) 0 ) ) 1877 { 1878 ::com::sun::star::drawing::PointSequence* pInnerSequence = 1879 (::com::sun::star::drawing::PointSequence*)rAny.getValue(); 1880 1881 bNoError = pInnerSequence != NULL; 1882 if ( bNoError ) 1883 { 1884 sal_uInt16 a, nInnerSequenceCount; 1885 1886 // Zeiger auf Arrays holen 1887 ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray(); 1888 if ( pArray != NULL ) 1889 { 1890 nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength(); 1891 aPolygon = Polygon( nInnerSequenceCount ); 1892 for( a = 0; a < nInnerSequenceCount; a++) 1893 { 1894 aPolygon[ a ] = Point( pArray->X, pArray->Y ); 1895 pArray++; 1896 } 1897 aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND ); 1898 } 1899 } 1900 } 1901 return aPolyPolygon; 1902 } 1903 1904 sal_Bool EscherPropertyContainer::CreatePolygonProperties( 1905 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 1906 sal_uInt32 nFlags, 1907 sal_Bool bBezier, 1908 ::com::sun::star::awt::Rectangle& rGeoRect, 1909 Polygon* pPolygon ) 1910 { 1911 static String sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) ); 1912 static String sPolyPolygon ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) ); 1913 1914 sal_Bool bRetValue = sal_True; 1915 sal_Bool bLine = ( nFlags & ESCHER_CREATEPOLYGON_LINE ) != 0; 1916 1917 PolyPolygon aPolyPolygon; 1918 1919 if ( pPolygon ) 1920 aPolyPolygon.Insert( *pPolygon, POLYPOLY_APPEND ); 1921 else 1922 { 1923 ::com::sun::star::uno::Any aAny; 1924 bRetValue = EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 1925 ( bBezier ) ? sPolyPolygonBezier : sPolyPolygon, sal_True ); 1926 if ( bRetValue ) 1927 { 1928 aPolyPolygon = GetPolyPolygon( aAny ); 1929 bRetValue = aPolyPolygon.Count() != 0; 1930 } 1931 } 1932 if ( bRetValue ) 1933 { 1934 if ( bLine ) 1935 { 1936 if ( ( aPolyPolygon.Count() == 1 ) && ( aPolyPolygon[ 0 ].GetSize() == 2 ) ) 1937 { 1938 const Polygon& rPoly = aPolyPolygon[ 0 ]; 1939 rGeoRect = ::com::sun::star::awt::Rectangle( 1940 rPoly[ 0 ].X(), 1941 rPoly[ 0 ].Y(), 1942 rPoly[ 1 ].X() - rPoly[ 0 ].X(), 1943 rPoly[ 1 ].Y() - rPoly[ 0 ].Y() ); 1944 } 1945 else 1946 bRetValue = sal_False; 1947 } 1948 else 1949 { 1950 Polygon aPolygon; 1951 1952 sal_uInt16 i, j, k, nPoints, nBezPoints, nPolyCount = aPolyPolygon.Count(); 1953 Rectangle aRect( aPolyPolygon.GetBoundRect() ); 1954 rGeoRect = ::com::sun::star::awt::Rectangle( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight() ); 1955 1956 for ( nBezPoints = nPoints = i = 0; i < nPolyCount; i++ ) 1957 { 1958 k = aPolyPolygon[ i ].GetSize(); 1959 nPoints = nPoints + k; 1960 for ( j = 0; j < k; j++ ) 1961 { 1962 if ( aPolyPolygon[ i ].GetFlags( j ) != POLY_CONTROL ) 1963 nBezPoints++; 1964 } 1965 } 1966 sal_uInt32 nVerticesBufSize = ( nPoints << 2 ) + 6; 1967 sal_uInt8* pVerticesBuf = new sal_uInt8[ nVerticesBufSize ]; 1968 1969 1970 sal_uInt32 nSegmentBufSize = ( ( nBezPoints << 2 ) + 8 ); 1971 if ( nPolyCount > 1 ) 1972 nSegmentBufSize += ( nPolyCount << 1 ); 1973 sal_uInt8* pSegmentBuf = new sal_uInt8[ nSegmentBufSize ]; 1974 1975 sal_uInt8* pPtr = pVerticesBuf; 1976 *pPtr++ = (sal_uInt8)( nPoints ); // Little endian 1977 *pPtr++ = (sal_uInt8)( nPoints >> 8 ); 1978 *pPtr++ = (sal_uInt8)( nPoints ); 1979 *pPtr++ = (sal_uInt8)( nPoints >> 8 ); 1980 *pPtr++ = (sal_uInt8)0xf0; 1981 *pPtr++ = (sal_uInt8)0xff; 1982 1983 for ( j = 0; j < nPolyCount; j++ ) 1984 { 1985 aPolygon = aPolyPolygon[ j ]; 1986 nPoints = aPolygon.GetSize(); 1987 for ( i = 0; i < nPoints; i++ ) // Punkte aus Polygon in Buffer schreiben 1988 { 1989 Point aPoint = aPolygon[ i ]; 1990 aPoint.X() -= rGeoRect.X; 1991 aPoint.Y() -= rGeoRect.Y; 1992 1993 *pPtr++ = (sal_uInt8)( aPoint.X() ); 1994 *pPtr++ = (sal_uInt8)( aPoint.X() >> 8 ); 1995 *pPtr++ = (sal_uInt8)( aPoint.Y() ); 1996 *pPtr++ = (sal_uInt8)( aPoint.Y() >> 8 ); 1997 } 1998 } 1999 2000 pPtr = pSegmentBuf; 2001 *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 1 ); 2002 *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 9 ); 2003 *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 1 ); 2004 *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 9 ); 2005 *pPtr++ = (sal_uInt8)2; 2006 *pPtr++ = (sal_uInt8)0; 2007 2008 for ( j = 0; j < nPolyCount; j++ ) 2009 { 2010 *pPtr++ = 0x0; // Polygon start 2011 *pPtr++ = 0x40; 2012 aPolygon = aPolyPolygon[ j ]; 2013 nPoints = aPolygon.GetSize(); 2014 for ( i = 0; i < nPoints; i++ ) // Polyflags in Buffer schreiben 2015 { 2016 *pPtr++ = 0; 2017 if ( bBezier ) 2018 *pPtr++ = 0xb3; 2019 else 2020 *pPtr++ = 0xac; 2021 if ( ( i + 1 ) != nPoints ) 2022 { 2023 *pPtr++ = 1; 2024 if ( aPolygon.GetFlags( i + 1 ) == POLY_CONTROL ) 2025 { 2026 *pPtr++ = 0x20; 2027 i += 2; 2028 } 2029 else 2030 *pPtr++ = 0; 2031 } 2032 } 2033 if ( nPolyCount > 1 ) 2034 { 2035 *pPtr++ = 1; // end of polygon 2036 *pPtr++ = 0x60; 2037 } 2038 } 2039 *pPtr++ = 0; 2040 *pPtr++ = 0x80; 2041 2042 AddOpt( ESCHER_Prop_geoRight, rGeoRect.Width ); 2043 AddOpt( ESCHER_Prop_geoBottom, rGeoRect.Height ); 2044 2045 AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex ); 2046 AddOpt( ESCHER_Prop_pVertices, sal_True, nVerticesBufSize - 6, (sal_uInt8*)pVerticesBuf, nVerticesBufSize ); 2047 AddOpt( ESCHER_Prop_pSegmentInfo, sal_True, nSegmentBufSize, (sal_uInt8*)pSegmentBuf, nSegmentBufSize ); 2048 } 2049 } 2050 return bRetValue; 2051 } 2052 2053 sal_Bool EscherPropertyContainer::CreateConnectorProperties( 2054 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape, 2055 EscherSolverContainer& rSolverContainer, ::com::sun::star::awt::Rectangle& rGeoRect, 2056 sal_uInt16& rShapeType, sal_uInt16& rShapeFlags ) 2057 { 2058 static String sEdgeKind ( RTL_CONSTASCII_USTRINGPARAM( "EdgeKind" ) ); 2059 static String sEdgeStartPoint ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartPoint" ) ); 2060 static String sEdgeEndPoint ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndPoint" ) ); 2061 static String sEdgeStartConnection ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartConnection" ) ); 2062 static String sEdgeEndConnection ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndConnection" ) ); 2063 2064 sal_Bool bRetValue = sal_False; 2065 rShapeType = rShapeFlags = 0; 2066 2067 if ( rXShape.is() ) 2068 { 2069 ::com::sun::star::awt::Point aStartPoint, aEndPoint; 2070 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXPropSet; 2071 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aShapeA, aShapeB; 2072 ::com::sun::star::uno::Any aAny( rXShape->queryInterface( ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) )); 2073 if ( aAny >>= aXPropSet ) 2074 { 2075 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeKind, sal_True ) ) 2076 { 2077 ::com::sun::star::drawing::ConnectorType eCt; 2078 aAny >>= eCt; 2079 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeStartPoint ) ) 2080 { 2081 aStartPoint = *(::com::sun::star::awt::Point*)aAny.getValue(); 2082 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeEndPoint ) ) 2083 { 2084 aEndPoint = *(::com::sun::star::awt::Point*)aAny.getValue(); 2085 2086 rShapeFlags = SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT | SHAPEFLAG_CONNECTOR; 2087 rGeoRect = ::com::sun::star::awt::Rectangle( aStartPoint.X, aStartPoint.Y, 2088 ( aEndPoint.X - aStartPoint.X ) + 1, ( aEndPoint.Y - aStartPoint.Y ) + 1 ); 2089 if ( rGeoRect.Height < 0 ) // justify 2090 { 2091 rShapeFlags |= SHAPEFLAG_FLIPV; 2092 rGeoRect.Y = aEndPoint.Y; 2093 rGeoRect.Height = -rGeoRect.Height; 2094 } 2095 if ( rGeoRect.Width < 0 ) 2096 { 2097 rShapeFlags |= SHAPEFLAG_FLIPH; 2098 rGeoRect.X = aEndPoint.X; 2099 rGeoRect.Width = -rGeoRect.Width; 2100 } 2101 sal_uInt32 nAdjustValue1, nAdjustValue2, nAdjustValue3; 2102 nAdjustValue1 = nAdjustValue2 = nAdjustValue3 = 0x2a30; 2103 2104 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeStartConnection ) ) 2105 aAny >>= aShapeA; 2106 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeEndConnection ) ) 2107 aAny >>= aShapeB; 2108 /* 2109 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine1Delta" ) ) ) ) 2110 { 2111 } 2112 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine2Delta" ) ) ) ) 2113 { 2114 } 2115 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine3Delta" ) ) ) ) 2116 { 2117 } 2118 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode1HorzDist" ) ) ) ) 2119 { 2120 } 2121 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode1VertDist" ) ) ) ) 2122 { 2123 } 2124 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode2HorzDist" ) ) ) ) 2125 { 2126 } 2127 if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode2VertDist" ) ) ) ) 2128 { 2129 } 2130 */ 2131 rSolverContainer.AddConnector( rXShape, aStartPoint, aShapeA, aEndPoint, aShapeB ); 2132 switch ( eCt ) 2133 { 2134 case ::com::sun::star::drawing::ConnectorType_CURVE : 2135 { 2136 rShapeType = ESCHER_ShpInst_CurvedConnector3; 2137 AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleCurved ); 2138 AddOpt( ESCHER_Prop_adjustValue, nAdjustValue1 ); 2139 AddOpt( ESCHER_Prop_adjust2Value, -(sal_Int32)nAdjustValue2 ); 2140 } 2141 break; 2142 2143 case ::com::sun::star::drawing::ConnectorType_STANDARD :// Connector 2->5 2144 { 2145 rShapeType = ESCHER_ShpInst_BentConnector3; 2146 AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleBent ); 2147 } 2148 break; 2149 2150 default: 2151 case ::com::sun::star::drawing::ConnectorType_LINE : 2152 case ::com::sun::star::drawing::ConnectorType_LINES : // Connector 2->5 2153 { 2154 rShapeType = ESCHER_ShpInst_StraightConnector1; 2155 AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleStraight ); 2156 } 2157 break; 2158 } 2159 CreateLineProperties( aXPropSet, sal_False ); 2160 bRetValue = bSuppressRotation = sal_True; 2161 } 2162 } 2163 } 2164 } 2165 } 2166 return bRetValue; 2167 } 2168 2169 sal_Bool EscherPropertyContainer::CreateShadowProperties( 2170 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet ) 2171 { 2172 ::com::sun::star::uno::Any aAny; 2173 2174 sal_Bool bHasShadow = sal_False; // shadow is possible only if at least a fillcolor, linecolor or graphic is set 2175 sal_uInt32 nLineFlags = 0; // default : shape has no line 2176 sal_uInt32 nFillFlags = 0x10; // shape is filled 2177 2178 GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags ); 2179 GetOpt( ESCHER_Prop_fNoFillHitTest, nFillFlags ); 2180 2181 sal_uInt32 nDummy; 2182 sal_Bool bGraphic = GetOpt( DFF_Prop_pib, nDummy ) || GetOpt( DFF_Prop_pibName, nDummy ) || GetOpt( DFF_Prop_pibFlags, nDummy ); 2183 2184 sal_uInt32 nShadowFlags = 0x20000; 2185 if ( ( nLineFlags & 8 ) || ( nFillFlags & 0x10 ) || bGraphic ) 2186 { 2187 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 2188 String( RTL_CONSTASCII_USTRINGPARAM( "Shadow" ) ), sal_True ) ) 2189 { 2190 if ( aAny >>= bHasShadow ) 2191 { 2192 if ( bHasShadow ) 2193 { 2194 nShadowFlags |= 2; 2195 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 2196 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowColor" ) ), sal_False ) ) 2197 AddOpt( ESCHER_Prop_shadowColor, ImplGetColor( *((sal_uInt32*)aAny.getValue()) ) ); 2198 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 2199 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowXDistance" ) ), sal_False ) ) 2200 AddOpt( ESCHER_Prop_shadowOffsetX, *((sal_Int32*)aAny.getValue()) * 360 ); 2201 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 2202 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowYDistance" ) ), sal_False ) ) 2203 AddOpt( ESCHER_Prop_shadowOffsetY, *((sal_Int32*)aAny.getValue()) * 360 ); 2204 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, 2205 String( RTL_CONSTASCII_USTRINGPARAM( "ShadowTransparence" ) ), sal_False ) ) 2206 AddOpt( ESCHER_Prop_shadowOpacity, 0x10000 - (((sal_uInt32)*((sal_uInt16*)aAny.getValue())) * 655 ) ); 2207 } 2208 } 2209 } 2210 } 2211 AddOpt( ESCHER_Prop_fshadowObscured, nShadowFlags ); 2212 return bHasShadow; 2213 } 2214 2215 // --------------------------------------------------------------------------------------------- 2216 2217 sal_Int32 EscherPropertyContainer::GetValueForEnhancedCustomShapeParameter( const ::com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, 2218 const std::vector< sal_Int32 >& rEquationOrder, sal_Bool bAdjustTrans ) 2219 { 2220 sal_Int32 nValue = 0; 2221 if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE ) 2222 { 2223 double fValue; 2224 if ( rParameter.Value >>= fValue ) 2225 nValue = (sal_Int32)fValue; 2226 } 2227 else 2228 rParameter.Value >>= nValue; 2229 2230 switch( rParameter.Type ) 2231 { 2232 case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION : 2233 { 2234 OSL_ASSERT((sal_uInt32)nValue < rEquationOrder.size()); 2235 if ( (sal_uInt32)nValue < rEquationOrder.size() ) 2236 { 2237 nValue = (sal_uInt16)rEquationOrder[ nValue ]; 2238 nValue |= (sal_uInt32)0x80000000; 2239 } 2240 } 2241 break; 2242 case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT: 2243 { 2244 if(bAdjustTrans) 2245 { 2246 sal_uInt32 nAdjustValue = 0; 2247 sal_Bool bGot = GetOpt((sal_uInt16)( DFF_Prop_adjustValue + nValue ), nAdjustValue); 2248 if(bGot) nValue = (sal_Int32)nAdjustValue; 2249 } 2250 } 2251 break; 2252 case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL : 2253 default: 2254 break; 2255 /* not sure if it is allowed to set following values 2256 (but they are not yet used) 2257 case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM : 2258 case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT : 2259 case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP : 2260 case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT : 2261 */ 2262 } 2263 return nValue; 2264 } 2265 2266 sal_Bool GetValueForEnhancedCustomShapeHandleParameter( sal_Int32& nRetValue, const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter ) 2267 { 2268 sal_Bool bSpecial = sal_False; 2269 nRetValue = 0; 2270 if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE ) 2271 { 2272 double fValue; 2273 if ( rParameter.Value >>= fValue ) 2274 nRetValue = (sal_Int32)fValue; 2275 } 2276 else 2277 rParameter.Value >>= nRetValue; 2278 2279 switch( rParameter.Type ) 2280 { 2281 case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION : 2282 { 2283 nRetValue += 3; 2284 bSpecial = sal_True; 2285 } 2286 break; 2287 case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT : 2288 { 2289 nRetValue += 0x100; 2290 bSpecial = sal_True; 2291 } 2292 break; 2293 case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP : 2294 case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT : 2295 { 2296 nRetValue = 0; 2297 bSpecial = sal_True; 2298 } 2299 break; 2300 case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT : 2301 case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM : 2302 { 2303 nRetValue = 1; 2304 bSpecial = sal_True; 2305 } 2306 break; 2307 case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL : 2308 { 2309 2310 } 2311 break; 2312 } 2313 return bSpecial; 2314 } 2315 2316 void ConvertEnhancedCustomShapeEquation( SdrObjCustomShape* pCustoShape, 2317 std::vector< EnhancedCustomShapeEquation >& rEquations, std::vector< sal_Int32 >& rEquationOrder ) 2318 { 2319 if ( pCustoShape ) 2320 { 2321 uno::Sequence< rtl::OUString > sEquationSource; 2322 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) ); 2323 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&) 2324 pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 2325 const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sEquations ); 2326 if ( pAny ) 2327 *pAny >>= sEquationSource; 2328 sal_Int32 nEquationSourceCount = sEquationSource.getLength(); 2329 if ( nEquationSourceCount ) 2330 { 2331 sal_Int32 i; 2332 for ( i = 0; i < nEquationSourceCount; i++ ) 2333 { 2334 EnhancedCustomShape2d aCustoShape2d( pCustoShape ); 2335 try 2336 { 2337 ::boost::shared_ptr< EnhancedCustomShape::ExpressionNode > aExpressNode( 2338 EnhancedCustomShape::FunctionParser::parseFunction( sEquationSource[ i ], aCustoShape2d ) ); 2339 com::sun::star::drawing::EnhancedCustomShapeParameter aPara( aExpressNode->fillNode( rEquations, NULL, 0 ) ); 2340 if ( aPara.Type != com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION ) 2341 { 2342 EnhancedCustomShapeEquation aEquation; 2343 aEquation.nOperation = 0; 2344 EnhancedCustomShape::FillEquationParameter( aPara, 0, aEquation ); 2345 rEquations.push_back( aEquation ); 2346 } 2347 } 2348 catch ( EnhancedCustomShape::ParseError& ) 2349 { 2350 EnhancedCustomShapeEquation aEquation; // ups, we should not be here, 2351 aEquation.nOperation = 0; // creating a default equation with value 1 2352 aEquation.nPara[ 0 ] = 1; // hoping that this will not break anything 2353 rEquations.push_back( aEquation ); 2354 } 2355 catch ( ... ) 2356 { 2357 EnhancedCustomShapeEquation aEquation; // #i112309# EnhancedCustomShape::Parse error 2358 aEquation.nOperation = 0; // not catched on linux platform 2359 aEquation.nPara[ 0 ] = 1; 2360 rEquations.push_back( aEquation ); 2361 } 2362 rEquationOrder.push_back( rEquations.size() - 1 ); 2363 } 2364 // now updating our old equation indices, they are marked with a bit in the hiword of nOperation 2365 std::vector< EnhancedCustomShapeEquation >::iterator aIter( rEquations.begin() ); 2366 std::vector< EnhancedCustomShapeEquation >::iterator aEnd ( rEquations.end() ); 2367 while( aIter != aEnd ) 2368 { 2369 sal_Int32 nMask = 0x20000000; 2370 for( i = 0; i < 3; i++ ) 2371 { 2372 if ( aIter->nOperation & nMask ) 2373 { 2374 aIter->nOperation ^= nMask; 2375 aIter->nPara[ i ] = rEquationOrder[ aIter->nPara[ i ] & 0x3ff ] | 0x400; 2376 } 2377 nMask <<= 1; 2378 } 2379 aIter++; 2380 } 2381 } 2382 } 2383 } 2384 2385 sal_Bool EscherPropertyContainer::IsDefaultObject( SdrObjCustomShape* pCustoShape , const MSO_SPT eShapeType ) 2386 { 2387 sal_Bool bIsDefaultObject = sal_False; 2388 switch(eShapeType) 2389 { 2390 //if the custom shape is not default shape of ppt, return sal_Fasle; 2391 case mso_sptTearDrop: 2392 return bIsDefaultObject; 2393 2394 default: 2395 break; 2396 } 2397 2398 if ( pCustoShape ) 2399 { 2400 if ( pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_EQUATIONS ) 2401 && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_VIEWBOX ) 2402 && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_PATH ) 2403 && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_GLUEPOINTS ) 2404 && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_SEGMENTS ) 2405 && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHX ) 2406 && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHY ) 2407 // && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_HANDLES ) 2408 && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_TEXTFRAMES ) ) 2409 bIsDefaultObject = sal_True; 2410 } 2411 2412 return bIsDefaultObject; 2413 } 2414 2415 void EscherPropertyContainer::LookForPolarHandles( const MSO_SPT eShapeType, sal_Int32& nAdjustmentsWhichNeedsToBeConverted ) 2416 { 2417 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eShapeType ); 2418 if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles ) 2419 { 2420 sal_Int32 k, nkCount = pDefCustomShape->nHandles; 2421 const SvxMSDffHandle* pData = pDefCustomShape->pHandles; 2422 for ( k = 0; k < nkCount; k++, pData++ ) 2423 { 2424 if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR ) 2425 { 2426 if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) ) 2427 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << k ); 2428 } 2429 } 2430 } 2431 } 2432 2433 sal_Bool EscherPropertyContainer::GetAdjustmentValue( const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue & rkProp, sal_Int32 nIndex, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, sal_Int32& nValue ) 2434 { 2435 if ( rkProp.State != beans::PropertyState_DIRECT_VALUE ) 2436 return sal_False; 2437 2438 sal_Bool bUseFixedFloat = ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << nIndex ) ) != 0; 2439 if ( rkProp.Value.getValueTypeClass() == uno::TypeClass_DOUBLE ) 2440 { 2441 double fValue(0.0); 2442 rkProp.Value >>= fValue; 2443 if ( bUseFixedFloat ) 2444 fValue *= 65536.0; 2445 nValue = (sal_Int32)fValue; 2446 } 2447 else 2448 { 2449 rkProp.Value >>= nValue; 2450 if ( bUseFixedFloat ) 2451 nValue <<= 16; 2452 } 2453 2454 return sal_True; 2455 } 2456 2457 void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeType, const uno::Reference< drawing::XShape > & rXShape ) 2458 { 2459 uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY ); 2460 if ( aXPropSet.is() ) 2461 { 2462 SdrObjCustomShape* pCustoShape = (SdrObjCustomShape*)GetSdrObjectFromXShape( rXShape ); 2463 if ( !pCustoShape ) return; 2464 const rtl::OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) ); 2465 uno::Any aGeoPropSet = aXPropSet->getPropertyValue( sCustomShapeGeometry ); 2466 uno::Sequence< beans::PropertyValue > aGeoPropSeq; 2467 if ( aGeoPropSet >>= aGeoPropSeq ) 2468 { 2469 const rtl::OUString sViewBox ( RTL_CONSTASCII_USTRINGPARAM( "ViewBox" ) ); 2470 const rtl::OUString sTextRotateAngle ( RTL_CONSTASCII_USTRINGPARAM( "TextRotateAngle" ) ); 2471 const rtl::OUString sExtrusion ( RTL_CONSTASCII_USTRINGPARAM( "Extrusion" ) ); 2472 const rtl::OUString sEquations ( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) ); 2473 const rtl::OUString sPath ( RTL_CONSTASCII_USTRINGPARAM( "Path" ) ); 2474 const rtl::OUString sTextPath ( RTL_CONSTASCII_USTRINGPARAM( "TextPath" ) ); 2475 const rtl::OUString sHandles ( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) ); 2476 const rtl::OUString sAdjustmentValues ( RTL_CONSTASCII_USTRINGPARAM( "AdjustmentValues" ) ); 2477 2478 const beans::PropertyValue* pAdjustmentValuesProp = NULL; 2479 const beans::PropertyValue* pPathCoordinatesProp = NULL; 2480 sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0; 2481 uno::Sequence< beans::PropertyValues > aHandlesPropSeq; 2482 sal_Bool bPredefinedHandlesUsed = sal_True; 2483 sal_Bool bIsDefaultObject = IsDefaultObject( pCustoShape , eShapeType); 2484 2485 // convert property "Equations" into std::vector< EnhancedCustomShapeEquationEquation > 2486 std::vector< EnhancedCustomShapeEquation > aEquations; 2487 std::vector< sal_Int32 > aEquationOrder; 2488 ConvertEnhancedCustomShapeEquation( pCustoShape, aEquations, aEquationOrder ); 2489 2490 sal_Int32 i, nCount = aGeoPropSeq.getLength(); 2491 for ( i = 0; i < nCount; i++ ) 2492 { 2493 const beans::PropertyValue& rProp = aGeoPropSeq[ i ]; 2494 if ( rProp.Name.equals( sViewBox ) ) 2495 { 2496 if ( !bIsDefaultObject ) 2497 { 2498 awt::Rectangle aViewBox; 2499 if ( rProp.Value >>= aViewBox ) 2500 { 2501 AddOpt( DFF_Prop_geoLeft, aViewBox.X ); 2502 AddOpt( DFF_Prop_geoTop, aViewBox.Y ); 2503 AddOpt( DFF_Prop_geoRight, aViewBox.X + aViewBox.Width ); 2504 AddOpt( DFF_Prop_geoBottom,aViewBox.Y + aViewBox.Height ); 2505 } 2506 } 2507 } 2508 else if ( rProp.Name.equals( sTextRotateAngle ) ) 2509 { 2510 double f = 0, fTextRotateAngle; 2511 if ( rProp.Value >>= f ) 2512 { 2513 fTextRotateAngle = fmod( f, 360.0 ); 2514 if ( fTextRotateAngle < 0 ) 2515 fTextRotateAngle = 360 + fTextRotateAngle; 2516 if ( ( fTextRotateAngle < 271.0 ) && ( fTextRotateAngle > 269.0 ) ) 2517 AddOpt( DFF_Prop_cdirFont, mso_cdir90 ); 2518 else if ( ( fTextRotateAngle < 181.0 ) && ( fTextRotateAngle > 179.0 ) ) 2519 AddOpt( DFF_Prop_cdirFont, mso_cdir180 ); 2520 else if ( ( fTextRotateAngle < 91.0 ) && ( fTextRotateAngle > 79.0 ) ) 2521 AddOpt( DFF_Prop_cdirFont, mso_cdir270 ); 2522 } 2523 } 2524 else if ( rProp.Name.equals( sExtrusion ) ) 2525 { 2526 uno::Sequence< beans::PropertyValue > aExtrusionPropSeq; 2527 if ( rProp.Value >>= aExtrusionPropSeq ) 2528 { 2529 sal_uInt32 nLightFaceFlagsOrg, nLightFaceFlags; 2530 sal_uInt32 nFillHarshFlagsOrg, nFillHarshFlags; 2531 nLightFaceFlagsOrg = nLightFaceFlags = 0x000001; 2532 nFillHarshFlagsOrg = nFillHarshFlags = 0x00001e; 2533 if ( GetOpt( DFF_Prop_fc3DLightFace, nLightFaceFlags ) ) 2534 nLightFaceFlagsOrg = nLightFaceFlags; 2535 if ( GetOpt( DFF_Prop_fc3DFillHarsh, nFillHarshFlags ) ) 2536 nFillHarshFlagsOrg = nFillHarshFlags; 2537 2538 sal_Int32 r, nrCount = aExtrusionPropSeq.getLength(); 2539 for ( r = 0; r < nrCount; r++ ) 2540 { 2541 const beans::PropertyValue& rrProp = aExtrusionPropSeq[ r ]; 2542 const rtl::OUString sExtrusionBrightness ( RTL_CONSTASCII_USTRINGPARAM( "Brightness" ) ); 2543 const rtl::OUString sExtrusionDepth ( RTL_CONSTASCII_USTRINGPARAM( "Depth" ) ); 2544 const rtl::OUString sExtrusionDiffusion ( RTL_CONSTASCII_USTRINGPARAM( "Diffusion" ) ); 2545 const rtl::OUString sExtrusionNumberOfLineSegments ( RTL_CONSTASCII_USTRINGPARAM( "NumberOfLineSegments" ) ); 2546 const rtl::OUString sExtrusionLightFace ( RTL_CONSTASCII_USTRINGPARAM( "LightFace" ) ); 2547 const rtl::OUString sExtrusionFirstLightHarsh ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightHarsh" ) ); 2548 const rtl::OUString sExtrusionSecondLightHarsh ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightHarsh" ) ); 2549 const rtl::OUString sExtrusionFirstLightLevel ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightLevel" ) ); 2550 const rtl::OUString sExtrusionSecondLightLevel ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightLevel" ) ); 2551 const rtl::OUString sExtrusionFirstLightDirection ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightDirection" ) ); 2552 const rtl::OUString sExtrusionSecondLightDirection ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightDirection" ) ); 2553 const rtl::OUString sExtrusionMetal ( RTL_CONSTASCII_USTRINGPARAM( "Metal" ) ); 2554 const rtl::OUString sExtrusionShadeMode ( RTL_CONSTASCII_USTRINGPARAM( "ShadeMode" ) ); 2555 const rtl::OUString sExtrusionRotateAngle ( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ); 2556 const rtl::OUString sExtrusionRotationCenter ( RTL_CONSTASCII_USTRINGPARAM( "RotationCenter" ) ); 2557 const rtl::OUString sExtrusionShininess ( RTL_CONSTASCII_USTRINGPARAM( "Shininess" ) ); 2558 const rtl::OUString sExtrusionSkew ( RTL_CONSTASCII_USTRINGPARAM( "Skew" ) ); 2559 const rtl::OUString sExtrusionSpecularity ( RTL_CONSTASCII_USTRINGPARAM( "Specularity" ) ); 2560 const rtl::OUString sExtrusionProjectionMode ( RTL_CONSTASCII_USTRINGPARAM( "ProjectionMode" ) ); 2561 const rtl::OUString sExtrusionViewPoint ( RTL_CONSTASCII_USTRINGPARAM( "ViewPoint" ) ); 2562 const rtl::OUString sExtrusionOrigin ( RTL_CONSTASCII_USTRINGPARAM( "Origin" ) ); 2563 const rtl::OUString sExtrusionColor ( RTL_CONSTASCII_USTRINGPARAM( "Color" ) ); 2564 2565 if ( rrProp.Name.equals( sExtrusion ) ) 2566 { 2567 sal_Bool bExtrusionOn = sal_Bool(); 2568 if ( rrProp.Value >>= bExtrusionOn ) 2569 { 2570 nLightFaceFlags |= 0x80000; 2571 if ( bExtrusionOn ) 2572 nLightFaceFlags |= 8; 2573 else 2574 nLightFaceFlags &=~8; 2575 } 2576 } 2577 else if ( rrProp.Name.equals( sExtrusionBrightness ) ) 2578 { 2579 double fExtrusionBrightness = 0; 2580 if ( rrProp.Value >>= fExtrusionBrightness ) 2581 AddOpt( DFF_Prop_c3DAmbientIntensity, (sal_Int32)( fExtrusionBrightness * 655.36 ) ); 2582 } 2583 else if ( rrProp.Name.equals( sExtrusionDepth ) ) 2584 { 2585 double fDepth = 0; 2586 double fFraction = 0; 2587 com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair; 2588 if ( ( rrProp.Value >>= aDepthParaPair ) && ( aDepthParaPair.First.Value >>= fDepth ) && ( aDepthParaPair.Second.Value >>= fFraction ) ) 2589 { 2590 double fForeDepth = fDepth * fFraction; 2591 double fBackDepth = fDepth - fForeDepth; 2592 2593 fBackDepth *= 360.0; 2594 AddOpt( DFF_Prop_c3DExtrudeBackward, (sal_Int32)fBackDepth ); 2595 2596 if ( fForeDepth != 0.0 ) 2597 { 2598 fForeDepth *= 360.0; 2599 AddOpt( DFF_Prop_c3DExtrudeForward, (sal_Int32)fForeDepth ); 2600 } 2601 } 2602 } 2603 else if ( rrProp.Name.equals( sExtrusionDiffusion ) ) 2604 { 2605 double fExtrusionDiffusion = 0; 2606 if ( rrProp.Value >>= fExtrusionDiffusion ) 2607 AddOpt( DFF_Prop_c3DDiffuseAmt, (sal_Int32)( fExtrusionDiffusion * 655.36 ) ); 2608 } 2609 else if ( rrProp.Name.equals( sExtrusionNumberOfLineSegments ) ) 2610 { 2611 sal_Int32 nExtrusionNumberOfLineSegments = 0; 2612 if ( rrProp.Value >>= nExtrusionNumberOfLineSegments ) 2613 AddOpt( DFF_Prop_c3DTolerance, nExtrusionNumberOfLineSegments ); 2614 } 2615 else if ( rrProp.Name.equals( sExtrusionLightFace ) ) 2616 { 2617 sal_Bool bExtrusionLightFace = sal_Bool(); 2618 if ( rrProp.Value >>= bExtrusionLightFace ) 2619 { 2620 nLightFaceFlags |= 0x10000; 2621 if ( bExtrusionLightFace ) 2622 nLightFaceFlags |= 1; 2623 else 2624 nLightFaceFlags &=~1; 2625 } 2626 } 2627 else if ( rrProp.Name.equals( sExtrusionFirstLightHarsh ) ) 2628 { 2629 sal_Bool bExtrusionFirstLightHarsh = sal_Bool(); 2630 if ( rrProp.Value >>= bExtrusionFirstLightHarsh ) 2631 { 2632 nFillHarshFlags |= 0x20000; 2633 if ( bExtrusionFirstLightHarsh ) 2634 nFillHarshFlags |= 2; 2635 else 2636 nFillHarshFlags &=~2; 2637 } 2638 } 2639 else if ( rrProp.Name.equals( sExtrusionSecondLightHarsh ) ) 2640 { 2641 sal_Bool bExtrusionSecondLightHarsh = sal_Bool(); 2642 if ( rrProp.Value >>= bExtrusionSecondLightHarsh ) 2643 { 2644 nFillHarshFlags |= 0x10000; 2645 if ( bExtrusionSecondLightHarsh ) 2646 nFillHarshFlags |= 1; 2647 else 2648 nFillHarshFlags &=~1; 2649 } 2650 } 2651 else if ( rrProp.Name.equals( sExtrusionFirstLightLevel ) ) 2652 { 2653 double fExtrusionFirstLightLevel = 0; 2654 if ( rrProp.Value >>= fExtrusionFirstLightLevel ) 2655 AddOpt( DFF_Prop_c3DKeyIntensity, (sal_Int32)( fExtrusionFirstLightLevel * 655.36 ) ); 2656 } 2657 else if ( rrProp.Name.equals( sExtrusionSecondLightLevel ) ) 2658 { 2659 double fExtrusionSecondLightLevel = 0; 2660 if ( rrProp.Value >>= fExtrusionSecondLightLevel ) 2661 AddOpt( DFF_Prop_c3DFillIntensity, (sal_Int32)( fExtrusionSecondLightLevel * 655.36 ) ); 2662 } 2663 else if ( rrProp.Name.equals( sExtrusionFirstLightDirection ) ) 2664 { 2665 drawing::Direction3D aExtrusionFirstLightDirection; 2666 if ( rrProp.Value >>= aExtrusionFirstLightDirection ) 2667 { 2668 AddOpt( DFF_Prop_c3DKeyX, (sal_Int32)aExtrusionFirstLightDirection.DirectionX ); 2669 AddOpt( DFF_Prop_c3DKeyY, (sal_Int32)aExtrusionFirstLightDirection.DirectionY ); 2670 AddOpt( DFF_Prop_c3DKeyZ, (sal_Int32)aExtrusionFirstLightDirection.DirectionZ ); 2671 } 2672 } 2673 else if ( rrProp.Name.equals( sExtrusionSecondLightDirection ) ) 2674 { 2675 drawing::Direction3D aExtrusionSecondLightPosition; 2676 if ( rrProp.Value >>= aExtrusionSecondLightPosition ) 2677 { 2678 AddOpt( DFF_Prop_c3DFillX, (sal_Int32)aExtrusionSecondLightPosition.DirectionX ); 2679 AddOpt( DFF_Prop_c3DFillY, (sal_Int32)aExtrusionSecondLightPosition.DirectionY ); 2680 AddOpt( DFF_Prop_c3DFillZ, (sal_Int32)aExtrusionSecondLightPosition.DirectionZ ); 2681 } 2682 } 2683 else if ( rrProp.Name.equals( sExtrusionMetal ) ) 2684 { 2685 sal_Bool bExtrusionMetal = sal_Bool(); 2686 if ( rrProp.Value >>= bExtrusionMetal ) 2687 { 2688 nLightFaceFlags |= 0x40000; 2689 if ( bExtrusionMetal ) 2690 nLightFaceFlags |= 4; 2691 else 2692 nLightFaceFlags &=~4; 2693 } 2694 } 2695 else if ( rrProp.Name.equals( sExtrusionShadeMode ) ) 2696 { 2697 drawing::ShadeMode eExtrusionShadeMode; 2698 if ( rrProp.Value >>= eExtrusionShadeMode ) 2699 { 2700 sal_uInt32 nRenderMode; 2701 switch( eExtrusionShadeMode ) 2702 { 2703 default: 2704 case drawing::ShadeMode_FLAT : 2705 case drawing::ShadeMode_PHONG : 2706 case drawing::ShadeMode_SMOOTH : 2707 nRenderMode = mso_FullRender; 2708 break; 2709 case drawing::ShadeMode_DRAFT : 2710 { 2711 nRenderMode = mso_Wireframe; 2712 } 2713 break; 2714 } 2715 AddOpt( DFF_Prop_c3DRenderMode, nRenderMode ); 2716 } 2717 } 2718 else if ( rrProp.Name.equals( sExtrusionRotateAngle ) ) 2719 { 2720 double fExtrusionAngleX = 0; 2721 double fExtrusionAngleY = 0; 2722 com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAnglePair; 2723 if ( ( rrProp.Value >>= aRotateAnglePair ) && ( aRotateAnglePair.First.Value >>= fExtrusionAngleX ) && ( aRotateAnglePair.Second.Value >>= fExtrusionAngleY ) ) 2724 { 2725 fExtrusionAngleX *= 65536; 2726 fExtrusionAngleY *= 65536; 2727 AddOpt( DFF_Prop_c3DXRotationAngle, (sal_Int32)fExtrusionAngleX ); 2728 AddOpt( DFF_Prop_c3DYRotationAngle, (sal_Int32)fExtrusionAngleY ); 2729 } 2730 } 2731 else if ( rrProp.Name.equals( sExtrusionRotationCenter ) ) 2732 { 2733 drawing::Direction3D aExtrusionRotationCenter; 2734 if ( rrProp.Value >>= aExtrusionRotationCenter ) 2735 { 2736 AddOpt( DFF_Prop_c3DRotationCenterX, (sal_Int32)( aExtrusionRotationCenter.DirectionX * 360.0 ) ); 2737 AddOpt( DFF_Prop_c3DRotationCenterY, (sal_Int32)( aExtrusionRotationCenter.DirectionY * 360.0 ) ); 2738 AddOpt( DFF_Prop_c3DRotationCenterZ, (sal_Int32)( aExtrusionRotationCenter.DirectionZ * 360.0 ) ); 2739 nFillHarshFlags &=~8; // don't use AutoRotationCenter; 2740 } 2741 } 2742 else if ( rrProp.Name.equals( sExtrusionShininess ) ) 2743 { 2744 double fExtrusionShininess = 0; 2745 if ( rrProp.Value >>= fExtrusionShininess ) 2746 AddOpt( DFF_Prop_c3DShininess, (sal_Int32)( fExtrusionShininess * 655.36 ) ); 2747 } 2748 else if ( rrProp.Name.equals( sExtrusionSkew ) ) 2749 { 2750 double fSkewAmount = 0; 2751 double fSkewAngle = 0; 2752 com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair; 2753 if ( ( rrProp.Value >>= aSkewParaPair ) && ( aSkewParaPair.First.Value >>= fSkewAmount ) && ( aSkewParaPair.Second.Value >>= fSkewAngle ) ) 2754 { 2755 AddOpt( DFF_Prop_c3DSkewAmount, (sal_Int32)fSkewAmount ); 2756 AddOpt( DFF_Prop_c3DSkewAngle, (sal_Int32)( fSkewAngle * 65536 ) ); 2757 } 2758 } 2759 else if ( rrProp.Name.equals( sExtrusionSpecularity ) ) 2760 { 2761 double fExtrusionSpecularity = 0; 2762 if ( rrProp.Value >>= fExtrusionSpecularity ) 2763 AddOpt( DFF_Prop_c3DSpecularAmt, (sal_Int32)( fExtrusionSpecularity * 1333 ) ); 2764 } 2765 else if ( rrProp.Name.equals( sExtrusionProjectionMode ) ) 2766 { 2767 drawing::ProjectionMode eExtrusionProjectionMode; 2768 if ( rrProp.Value >>= eExtrusionProjectionMode ) 2769 { 2770 nFillHarshFlags |= 0x40000; 2771 if ( eExtrusionProjectionMode == drawing::ProjectionMode_PARALLEL ) 2772 nFillHarshFlags |= 4; 2773 else 2774 nFillHarshFlags &=~4; 2775 } 2776 } 2777 else if ( rrProp.Name.equals( sExtrusionViewPoint ) ) 2778 { 2779 drawing::Position3D aExtrusionViewPoint; 2780 if ( rrProp.Value >>= aExtrusionViewPoint ) 2781 { 2782 aExtrusionViewPoint.PositionX *= 360.0; 2783 aExtrusionViewPoint.PositionY *= 360.0; 2784 aExtrusionViewPoint.PositionZ *= 360.0; 2785 AddOpt( DFF_Prop_c3DXViewpoint, (sal_Int32)aExtrusionViewPoint.PositionX ); 2786 AddOpt( DFF_Prop_c3DYViewpoint, (sal_Int32)aExtrusionViewPoint.PositionY ); 2787 AddOpt( DFF_Prop_c3DZViewpoint, (sal_Int32)aExtrusionViewPoint.PositionZ ); 2788 } 2789 } 2790 else if ( rrProp.Name.equals( sExtrusionOrigin ) ) 2791 { 2792 double fExtrusionOriginX = 0; 2793 double fExtrusionOriginY = 0; 2794 com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginPair; 2795 if ( ( rrProp.Value >>= aOriginPair ) && ( aOriginPair.First.Value >>= fExtrusionOriginX ) && ( aOriginPair.Second.Value >>= fExtrusionOriginY ) ) 2796 { 2797 AddOpt( DFF_Prop_c3DOriginX, (sal_Int32)( fExtrusionOriginX * 65536 ) ); 2798 AddOpt( DFF_Prop_c3DOriginY, (sal_Int32)( fExtrusionOriginY * 65536 ) ); 2799 } 2800 } 2801 else if ( rrProp.Name.equals( sExtrusionColor ) ) 2802 { 2803 sal_Bool bExtrusionColor = sal_Bool(); 2804 if ( rrProp.Value >>= bExtrusionColor ) 2805 { 2806 nLightFaceFlags |= 0x20000; 2807 if ( bExtrusionColor ) 2808 { 2809 nLightFaceFlags |= 2; 2810 uno::Any aFillColor2; 2811 if ( EscherPropertyValueHelper::GetPropertyValue( aFillColor2, aXPropSet, 2812 String( RTL_CONSTASCII_USTRINGPARAM( "FillColor2" ) ), sal_True ) ) 2813 { 2814 sal_uInt32 nFillColor = ImplGetColor( *((sal_uInt32*)aFillColor2.getValue()) ); 2815 AddOpt( DFF_Prop_c3DExtrusionColor, nFillColor ); 2816 } 2817 } 2818 else 2819 nLightFaceFlags &=~2; 2820 } 2821 } 2822 } 2823 if ( nLightFaceFlags != nLightFaceFlagsOrg ) 2824 AddOpt( DFF_Prop_fc3DLightFace, nLightFaceFlags ); 2825 if ( nFillHarshFlags != nFillHarshFlagsOrg ) 2826 AddOpt( DFF_Prop_fc3DFillHarsh, nFillHarshFlags ); 2827 } 2828 } 2829 else if ( rProp.Name.equals( sEquations ) ) 2830 { 2831 if ( !bIsDefaultObject ) 2832 { 2833 sal_uInt16 nElements = (sal_uInt16)aEquations.size(); 2834 if ( nElements ) 2835 { 2836 sal_uInt16 nElementSize = 8; 2837 sal_uInt32 nStreamSize = nElementSize * nElements + 6; 2838 SvMemoryStream aOut( nStreamSize ); 2839 aOut << nElements 2840 << nElements 2841 << nElementSize; 2842 2843 std::vector< EnhancedCustomShapeEquation >::const_iterator aIter( aEquations.begin() ); 2844 std::vector< EnhancedCustomShapeEquation >::const_iterator aEnd ( aEquations.end() ); 2845 while( aIter != aEnd ) 2846 { 2847 aOut << (sal_uInt16)aIter->nOperation 2848 << (sal_Int16)aIter->nPara[ 0 ] 2849 << (sal_Int16)aIter->nPara[ 1 ] 2850 << (sal_Int16)aIter->nPara[ 2 ]; 2851 aIter++; 2852 } 2853 sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ]; 2854 memcpy( pBuf, aOut.GetData(), nStreamSize ); 2855 AddOpt( DFF_Prop_pFormulas, sal_True, nStreamSize - 6, pBuf, nStreamSize ); 2856 } 2857 else 2858 { 2859 sal_uInt8* pBuf = new sal_uInt8[ 1 ]; 2860 AddOpt( DFF_Prop_pFormulas, sal_True, 0, pBuf, 0 ); 2861 } 2862 } 2863 } 2864 else if ( rProp.Name.equals( sPath ) ) 2865 { 2866 uno::Sequence< beans::PropertyValue > aPathPropSeq; 2867 if ( rProp.Value >>= aPathPropSeq ) 2868 { 2869 sal_uInt32 nPathFlags, nPathFlagsOrg; 2870 nPathFlagsOrg = nPathFlags = 0x39; 2871 if ( GetOpt( DFF_Prop_fFillOK, nPathFlags ) ) 2872 nPathFlagsOrg = nPathFlags; 2873 2874 sal_Int32 r, nrCount = aPathPropSeq.getLength(); 2875 for ( r = 0; r < nrCount; r++ ) 2876 { 2877 const beans::PropertyValue& rrProp = aPathPropSeq[ r ]; 2878 const rtl::OUString sPathExtrusionAllowed ( RTL_CONSTASCII_USTRINGPARAM( "ExtrusionAllowed" ) ); 2879 const rtl::OUString sPathConcentricGradientFillAllowed ( RTL_CONSTASCII_USTRINGPARAM( "ConcentricGradientFillAllowed" ) ); 2880 const rtl::OUString sPathTextPathAllowed ( RTL_CONSTASCII_USTRINGPARAM( "TextPathAllowed" ) ); 2881 const rtl::OUString sPathCoordinates ( RTL_CONSTASCII_USTRINGPARAM( "Coordinates" ) ); 2882 const rtl::OUString sPathGluePoints ( RTL_CONSTASCII_USTRINGPARAM( "GluePoints" ) ); 2883 const rtl::OUString sPathGluePointType ( RTL_CONSTASCII_USTRINGPARAM( "GluePointType" ) ); 2884 const rtl::OUString sPathSegments ( RTL_CONSTASCII_USTRINGPARAM( "Segments" ) ); 2885 const rtl::OUString sPathStretchX ( RTL_CONSTASCII_USTRINGPARAM( "StretchX" ) ); 2886 const rtl::OUString sPathStretchY ( RTL_CONSTASCII_USTRINGPARAM( "StretchY" ) ); 2887 const rtl::OUString sPathTextFrames ( RTL_CONSTASCII_USTRINGPARAM( "TextFrames" ) ); 2888 2889 if ( rrProp.Name.equals( sPathExtrusionAllowed ) ) 2890 { 2891 sal_Bool bExtrusionAllowed = sal_Bool(); 2892 if ( rrProp.Value >>= bExtrusionAllowed ) 2893 { 2894 nPathFlags |= 0x100000; 2895 if ( bExtrusionAllowed ) 2896 nPathFlags |= 16; 2897 else 2898 nPathFlags &=~16; 2899 } 2900 } 2901 else if ( rrProp.Name.equals( sPathConcentricGradientFillAllowed ) ) 2902 { 2903 sal_Bool bConcentricGradientFillAllowed = sal_Bool(); 2904 if ( rrProp.Value >>= bConcentricGradientFillAllowed ) 2905 { 2906 nPathFlags |= 0x20000; 2907 if ( bConcentricGradientFillAllowed ) 2908 nPathFlags |= 2; 2909 else 2910 nPathFlags &=~2; 2911 } 2912 } 2913 else if ( rrProp.Name.equals( sPathTextPathAllowed ) ) 2914 { 2915 sal_Bool bTextPathAllowed = sal_Bool(); 2916 if ( rrProp.Value >>= bTextPathAllowed ) 2917 { 2918 nPathFlags |= 0x40000; 2919 if ( bTextPathAllowed ) 2920 nPathFlags |= 4; 2921 else 2922 nPathFlags &=~4; 2923 } 2924 } 2925 else if ( rrProp.Name.equals( sPathCoordinates ) ) 2926 { 2927 if ( !bIsDefaultObject ) 2928 pPathCoordinatesProp = &rrProp; 2929 } 2930 else if ( rrProp.Name.equals( sPathGluePoints ) ) 2931 { 2932 if ( !bIsDefaultObject ) 2933 { 2934 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> aGluePoints; 2935 if ( rrProp.Value >>= aGluePoints ) 2936 { 2937 // creating the vertices 2938 sal_uInt16 nElements = (sal_uInt16)aGluePoints.getLength(); 2939 if ( nElements ) 2940 { 2941 sal_uInt16 j, nElementSize = 8; 2942 sal_uInt32 nStreamSize = nElementSize * nElements + 6; 2943 SvMemoryStream aOut( nStreamSize ); 2944 aOut << nElements 2945 << nElements 2946 << nElementSize; 2947 for( j = 0; j < nElements; j++ ) 2948 { 2949 sal_Int32 X = GetValueForEnhancedCustomShapeParameter( aGluePoints[ j ].First, aEquationOrder ); 2950 sal_Int32 Y = GetValueForEnhancedCustomShapeParameter( aGluePoints[ j ].Second, aEquationOrder ); 2951 aOut << X 2952 << Y; 2953 } 2954 sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ]; 2955 memcpy( pBuf, aOut.GetData(), nStreamSize ); 2956 AddOpt( DFF_Prop_connectorPoints, sal_True, nStreamSize - 6, pBuf, nStreamSize ); // -6 2957 } 2958 else 2959 { 2960 sal_uInt8* pBuf = new sal_uInt8[ 1 ]; 2961 AddOpt( DFF_Prop_connectorPoints, sal_True, 0, pBuf, 0 ); 2962 } 2963 } 2964 } 2965 } 2966 else if ( rrProp.Name.equals( sPathGluePointType ) ) 2967 { 2968 sal_Int16 nGluePointType = sal_Int16(); 2969 if ( rrProp.Value >>= nGluePointType ) 2970 AddOpt( DFF_Prop_connectorType, (sal_uInt16)nGluePointType ); 2971 } 2972 else if ( rrProp.Name.equals( sPathSegments ) ) 2973 { 2974 if ( !bIsDefaultObject ) 2975 { 2976 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments; 2977 if ( rrProp.Value >>= aSegments ) 2978 { 2979 // creating seginfo 2980 if ( (sal_uInt16)aSegments.getLength() ) 2981 { 2982 sal_uInt16 j, nElements = (sal_uInt16)aSegments.getLength(); 2983 sal_uInt16 nElementSize = 2; 2984 sal_uInt32 nStreamSize = nElementSize * nElements + 6; 2985 SvMemoryStream aOut( nStreamSize ); 2986 aOut << nElements 2987 << nElements 2988 << nElementSize; 2989 for ( j = 0; j < nElements; j++ ) 2990 { 2991 sal_uInt16 nVal = (sal_uInt16)aSegments[ j ].Count; 2992 switch( aSegments[ j ].Command ) 2993 { 2994 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::UNKNOWN : 2995 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO : break; 2996 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO : 2997 { 2998 nVal = 0x4000; 2999 } 3000 break; 3001 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO : 3002 { 3003 nVal |= 0x2000; 3004 } 3005 break; 3006 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH : 3007 { 3008 nVal = 0x6001; 3009 } 3010 break; 3011 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH : 3012 { 3013 nVal = 0x8000; 3014 } 3015 break; 3016 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL : 3017 { 3018 nVal = 0xaa00; 3019 } 3020 break; 3021 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE : 3022 { 3023 nVal = 0xab00; 3024 } 3025 break; 3026 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO : 3027 { 3028 nVal *= 3; 3029 nVal |= 0xa100; 3030 } 3031 break; 3032 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE : 3033 { 3034 nVal *= 3; 3035 nVal |= 0xa200; 3036 } 3037 break; 3038 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO : 3039 { 3040 nVal <<= 2; 3041 nVal |= 0xa300; 3042 } 3043 break; 3044 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC : 3045 { 3046 nVal <<= 2; 3047 nVal |= 0xa400; 3048 } 3049 break; 3050 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO : 3051 { 3052 nVal <<= 2; 3053 nVal |= 0xa500; 3054 } 3055 break; 3056 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC : 3057 { 3058 nVal <<= 2; 3059 nVal |= 0xa600; 3060 } 3061 break; 3062 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX : 3063 { 3064 nVal |= 0xa700; 3065 } 3066 break; 3067 case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY : 3068 { 3069 nVal |= 0xa800; 3070 } 3071 break; 3072 } 3073 aOut << nVal; 3074 } 3075 sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ]; 3076 memcpy( pBuf, aOut.GetData(), nStreamSize ); 3077 AddOpt( DFF_Prop_pSegmentInfo, sal_False, nStreamSize - 6, pBuf, nStreamSize ); 3078 } 3079 else 3080 { 3081 sal_uInt8* pBuf = new sal_uInt8[ 1 ]; 3082 AddOpt( DFF_Prop_pSegmentInfo, sal_True, 0, pBuf, 0 ); 3083 } 3084 } 3085 } 3086 } 3087 else if ( rrProp.Name.equals( sPathStretchX ) ) 3088 { 3089 if ( !bIsDefaultObject ) 3090 { 3091 sal_Int32 nStretchX = 0; 3092 if ( rrProp.Value >>= nStretchX ) 3093 AddOpt( DFF_Prop_stretchPointX, nStretchX ); 3094 } 3095 } 3096 else if ( rrProp.Name.equals( sPathStretchY ) ) 3097 { 3098 if ( !bIsDefaultObject ) 3099 { 3100 sal_Int32 nStretchY = 0; 3101 if ( rrProp.Value >>= nStretchY ) 3102 AddOpt( DFF_Prop_stretchPointY, nStretchY ); 3103 } 3104 } 3105 else if ( rrProp.Name.equals( sPathTextFrames ) ) 3106 { 3107 if ( !bIsDefaultObject ) 3108 { 3109 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames; 3110 if ( rrProp.Value >>= aPathTextFrames ) 3111 { 3112 if ( (sal_uInt16)aPathTextFrames.getLength() ) 3113 { 3114 sal_uInt16 j, nElements = (sal_uInt16)aPathTextFrames.getLength(); 3115 sal_uInt16 nElementSize = 16; 3116 sal_uInt32 nStreamSize = nElementSize * nElements + 6; 3117 SvMemoryStream aOut( nStreamSize ); 3118 aOut << nElements 3119 << nElements 3120 << nElementSize; 3121 for ( j = 0; j < nElements; j++ ) 3122 { 3123 sal_Int32 nLeft = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].TopLeft.First, aEquationOrder ); 3124 sal_Int32 nTop = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].TopLeft.Second, aEquationOrder ); 3125 sal_Int32 nRight = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].BottomRight.First, aEquationOrder ); 3126 sal_Int32 nBottom = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].BottomRight.Second, aEquationOrder ); 3127 3128 aOut << nLeft 3129 << nTop 3130 << nRight 3131 << nBottom; 3132 } 3133 sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ]; 3134 memcpy( pBuf, aOut.GetData(), nStreamSize ); 3135 AddOpt( DFF_Prop_textRectangles, sal_True, nStreamSize - 6, pBuf, nStreamSize ); 3136 } 3137 else 3138 { 3139 sal_uInt8* pBuf = new sal_uInt8[ 1 ]; 3140 AddOpt( DFF_Prop_textRectangles, sal_True, 0, pBuf, 0 ); 3141 } 3142 } 3143 } 3144 } 3145 } 3146 if ( nPathFlags != nPathFlagsOrg ) 3147 AddOpt( DFF_Prop_fFillOK, nPathFlags ); 3148 } 3149 } 3150 else if ( rProp.Name.equals( sTextPath ) ) 3151 { 3152 uno::Sequence< beans::PropertyValue > aTextPathPropSeq; 3153 if ( rProp.Value >>= aTextPathPropSeq ) 3154 { 3155 sal_uInt32 nTextPathFlagsOrg, nTextPathFlags; 3156 nTextPathFlagsOrg = nTextPathFlags = 0xffff1000; // default 3157 if ( GetOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags ) ) 3158 nTextPathFlagsOrg = nTextPathFlags; 3159 3160 sal_Int32 r, nrCount = aTextPathPropSeq.getLength(); 3161 for ( r = 0; r < nrCount; r++ ) 3162 { 3163 const beans::PropertyValue& rrProp = aTextPathPropSeq[ r ]; 3164 const rtl::OUString sTextPathMode ( RTL_CONSTASCII_USTRINGPARAM( "TextPathMode" ) ); 3165 const rtl::OUString sTextPathScaleX ( RTL_CONSTASCII_USTRINGPARAM( "ScaleX" ) ); 3166 const rtl::OUString sSameLetterHeights ( RTL_CONSTASCII_USTRINGPARAM( "SameLetterHeights" ) ); 3167 3168 if ( rrProp.Name.equals( sTextPath ) ) 3169 { 3170 sal_Bool bTextPathOn = sal_Bool(); 3171 if ( rrProp.Value >>= bTextPathOn ) 3172 { 3173 nTextPathFlags |= 0x40000000; 3174 if ( bTextPathOn ) 3175 { 3176 nTextPathFlags |= 0x4000; 3177 3178 sal_uInt32 nPathFlags = 0x39; 3179 GetOpt( DFF_Prop_fFillOK, nPathFlags ); // SJ: can be removed if we are supporting the TextPathAllowed property in XML 3180 nPathFlags |= 0x40004; 3181 AddOpt( DFF_Prop_fFillOK, nPathFlags ); 3182 } 3183 else 3184 nTextPathFlags &=~0x4000; 3185 } 3186 } 3187 else if ( rrProp.Name.equals( sTextPathMode ) ) 3188 { 3189 com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode; 3190 if ( rrProp.Value >>= eTextPathMode ) 3191 { 3192 nTextPathFlags |= 0x05000000; 3193 nTextPathFlags &=~0x500; // TextPathMode_NORMAL 3194 if ( eTextPathMode == com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH ) 3195 nTextPathFlags |= 0x100; 3196 else if ( eTextPathMode == com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE ) 3197 nTextPathFlags |= 0x500; 3198 } 3199 } 3200 else if ( rrProp.Name.equals( sTextPathScaleX ) ) 3201 { 3202 sal_Bool bTextPathScaleX = sal_Bool(); 3203 if ( rrProp.Value >>= bTextPathScaleX ) 3204 { 3205 nTextPathFlags |= 0x00400000; 3206 if ( bTextPathScaleX ) 3207 nTextPathFlags |= 0x40; 3208 else 3209 nTextPathFlags &=~0x40; 3210 } 3211 } 3212 else if ( rrProp.Name.equals( sSameLetterHeights ) ) 3213 { 3214 sal_Bool bSameLetterHeights = sal_Bool(); 3215 if ( rrProp.Value >>= bSameLetterHeights ) 3216 { 3217 nTextPathFlags |= 0x00800000; 3218 if ( bSameLetterHeights ) 3219 nTextPathFlags |= 0x80; 3220 else 3221 nTextPathFlags &=~0x80; 3222 } 3223 } 3224 } 3225 if ( nTextPathFlags & 0x4000 ) // Is FontWork ? 3226 { 3227 // FontWork Text 3228 rtl::OUString aText; 3229 uno::Reference< text::XSimpleText > xText( rXShape, uno::UNO_QUERY ); 3230 if ( xText.is() ) 3231 aText = xText->getString(); 3232 if ( !aText.getLength() ) 3233 aText = ::rtl::OUString::createFromAscii( "your text" ); // todo: moving into a resource 3234 AddOpt( DFF_Prop_gtextUNICODE, aText ); 3235 3236 // FontWork Font 3237 rtl::OUString aFontName; 3238 const rtl::OUString sCharFontName ( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) ); 3239 uno::Any aAny = aXPropSet->getPropertyValue( sCharFontName ); 3240 aAny >>= aFontName; 3241 if ( !aFontName.getLength() ) 3242 aFontName = ::rtl::OUString::createFromAscii( "Arial Black" ); 3243 AddOpt( DFF_Prop_gtextFont, aFontName ); 3244 3245 sal_Int16 nCharScaleWidth = 100; 3246 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharScaleWidth" ) ), sal_True ) ) 3247 { 3248 if ( aAny >>= nCharScaleWidth ) 3249 { 3250 if ( nCharScaleWidth != 100 ) 3251 { 3252 sal_Int32 nVal = nCharScaleWidth * 655; 3253 AddOpt( DFF_Prop_gtextSpacing, nVal ); 3254 } 3255 } 3256 } 3257 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharHeight" ) ), sal_True ) ) 3258 { 3259 float fCharHeight = 0.0; 3260 if ( aAny >>= fCharHeight ) 3261 { 3262 sal_Int32 nTextSize = static_cast< sal_Int32 > ( fCharHeight * 65536 ); 3263 AddOpt(ESCHER_Prop_gtextSize, nTextSize); 3264 } 3265 } 3266 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharKerning" ) ), sal_True ) ) 3267 { 3268 sal_Int16 nCharKerning = sal_Int16(); 3269 if ( aAny >>= nCharKerning ) 3270 { 3271 nTextPathFlags |= 0x10000000; 3272 if ( nCharKerning ) 3273 nTextPathFlags |= 0x1000; 3274 else 3275 nTextPathFlags &=~0x1000; 3276 } 3277 } 3278 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) ), sal_True ) ) 3279 { 3280 awt::FontSlant eFontSlant; 3281 if ( aAny >>= eFontSlant ) 3282 { 3283 nTextPathFlags |= 0x100010; 3284 if ( eFontSlant != awt::FontSlant_NONE ) 3285 nTextPathFlags |= 0x10; 3286 else 3287 nTextPathFlags &=~0x10; 3288 } 3289 } 3290 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ), sal_True ) ) 3291 { 3292 float fFontWidth = 0; 3293 if ( aAny >>= fFontWidth ) 3294 { 3295 nTextPathFlags |= 0x200020; 3296 if ( fFontWidth > awt::FontWeight::NORMAL ) 3297 nTextPathFlags |= 0x20; 3298 else 3299 nTextPathFlags &=~0x20; 3300 } 3301 } 3302 //export gTextAlign attr 3303 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextHorizontalAdjust" ) ), sal_True ) ) 3304 { 3305 MSO_GeoTextAlign gTextAlign = mso_alignTextCenter; 3306 // SdrFitToSizeType eFTS( ((SdrTextFitToSizeTypeItem&)pCustoShape->GetMergedItem( SDRATTR_TEXT_FITTOSIZE )).GetValue() ); 3307 drawing::TextHorizontalAdjust eHA( drawing::TextHorizontalAdjust_LEFT ); 3308 aAny >>= eHA; 3309 switch( eHA ) 3310 { 3311 case drawing::TextHorizontalAdjust_LEFT : 3312 gTextAlign = mso_alignTextLeft; 3313 break; 3314 case drawing::TextHorizontalAdjust_CENTER: 3315 gTextAlign = mso_alignTextCenter; 3316 break; 3317 case drawing::TextHorizontalAdjust_RIGHT: 3318 gTextAlign = mso_alignTextRight; 3319 break; 3320 case drawing::TextHorizontalAdjust_BLOCK: 3321 { 3322 SdrFitToSizeType eFTS( ((SdrTextFitToSizeTypeItem&)pCustoShape->GetMergedItem( SDRATTR_TEXT_FITTOSIZE )).GetValue() ); 3323 if ( eFTS == SDRTEXTFIT_ALLLINES) 3324 { 3325 gTextAlign = mso_alignTextStretch; 3326 } 3327 else 3328 { 3329 gTextAlign = mso_alignTextWordJust; 3330 } 3331 break; 3332 } 3333 default: 3334 break; 3335 } 3336 AddOpt(DFF_Prop_gtextAlign,gTextAlign); 3337 } 3338 } 3339 if((nTextPathFlags & 0x4000) != 0) //Is Font work 3340 { 3341 OutlinerParaObject* pOutlinerParaObject = pCustoShape->GetOutlinerParaObject(); 3342 if ( pOutlinerParaObject && pOutlinerParaObject->IsVertical() ) 3343 nTextPathFlags |= 0x2000; 3344 } 3345 if ( nTextPathFlags != nTextPathFlagsOrg ) 3346 AddOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags ); 3347 } 3348 } 3349 else if ( rProp.Name.equals( sHandles ) ) 3350 { 3351 if ( !bIsDefaultObject ) 3352 { 3353 bPredefinedHandlesUsed = sal_False; 3354 if ( rProp.Value >>= aHandlesPropSeq ) 3355 { 3356 sal_uInt16 nElements = (sal_uInt16)aHandlesPropSeq.getLength(); 3357 if ( nElements ) 3358 { 3359 const rtl::OUString sHandle ( RTL_CONSTASCII_USTRINGPARAM( "Handle" ) ); 3360 3361 sal_uInt16 k, j, nElementSize = 36; 3362 sal_uInt32 nStreamSize = nElementSize * nElements + 6; 3363 SvMemoryStream aOut( nStreamSize ); 3364 aOut << nElements 3365 << nElements 3366 << nElementSize; 3367 3368 for ( k = 0; k < nElements; k++ ) 3369 { 3370 sal_uInt32 nFlags = 0; 3371 sal_Int32 nXPosition = 0; 3372 sal_Int32 nYPosition = 0; 3373 sal_Int32 nXMap = 0; 3374 sal_Int32 nYMap = 0; 3375 sal_Int32 nXRangeMin = 0x80000000; 3376 sal_Int32 nXRangeMax = 0x7fffffff; 3377 sal_Int32 nYRangeMin = 0x80000000; 3378 sal_Int32 nYRangeMax = 0x7fffffff; 3379 3380 const uno::Sequence< beans::PropertyValue >& rPropSeq = aHandlesPropSeq[ k ]; 3381 for ( j = 0; j < rPropSeq.getLength(); j++ ) 3382 { 3383 const beans::PropertyValue& rPropVal = rPropSeq[ j ]; 3384 3385 const rtl::OUString sPosition ( RTL_CONSTASCII_USTRINGPARAM( "Position" ) ); 3386 const rtl::OUString sMirroredX ( RTL_CONSTASCII_USTRINGPARAM( "MirroredX" ) ); 3387 const rtl::OUString sMirroredY ( RTL_CONSTASCII_USTRINGPARAM( "MirroredY" ) ); 3388 const rtl::OUString sSwitched ( RTL_CONSTASCII_USTRINGPARAM( "Switched" ) ); 3389 const rtl::OUString sPolar ( RTL_CONSTASCII_USTRINGPARAM( "Polar" ) ); 3390 // const rtl::OUString sMap ( RTL_CONSTASCII_USTRINGPARAM( "Map" ) ); 3391 const rtl::OUString sRadiusRangeMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMinimum" ) ); 3392 const rtl::OUString sRadiusRangeMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMaximum" ) ); 3393 const rtl::OUString sRangeXMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMinimum" ) ); 3394 const rtl::OUString sRangeXMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMaximum" ) ); 3395 const rtl::OUString sRangeYMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMinimum" ) ); 3396 const rtl::OUString sRangeYMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMaximum" ) ); 3397 3398 if ( rPropVal.Name.equals( sPosition ) ) 3399 { 3400 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition; 3401 if ( rPropVal.Value >>= aPosition ) 3402 { 3403 GetValueForEnhancedCustomShapeHandleParameter( nXPosition, aPosition.First ); 3404 GetValueForEnhancedCustomShapeHandleParameter( nYPosition, aPosition.Second ); 3405 } 3406 } 3407 else if ( rPropVal.Name.equals( sMirroredX ) ) 3408 { 3409 sal_Bool bMirroredX = sal_Bool(); 3410 if ( rPropVal.Value >>= bMirroredX ) 3411 { 3412 if ( bMirroredX ) 3413 nFlags |= 1; 3414 } 3415 } 3416 else if ( rPropVal.Name.equals( sMirroredY ) ) 3417 { 3418 sal_Bool bMirroredY = sal_Bool(); 3419 if ( rPropVal.Value >>= bMirroredY ) 3420 { 3421 if ( bMirroredY ) 3422 nFlags |= 2; 3423 } 3424 } 3425 else if ( rPropVal.Name.equals( sSwitched ) ) 3426 { 3427 sal_Bool bSwitched = sal_Bool(); 3428 if ( rPropVal.Value >>= bSwitched ) 3429 { 3430 if ( bSwitched ) 3431 nFlags |= 4; 3432 } 3433 } 3434 else if ( rPropVal.Name.equals( sPolar ) ) 3435 { 3436 com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar; 3437 if ( rPropVal.Value >>= aPolar ) 3438 { 3439 if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aPolar.First ) ) 3440 nFlags |= 0x800; 3441 if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aPolar.Second ) ) 3442 nFlags |= 0x1000; 3443 nFlags |= 8; 3444 } 3445 } 3446 /* seems not to be used. 3447 else if ( rPropVal.Name.equals( sMap ) ) 3448 { 3449 com::sun::star::drawing::EnhancedCustomShapeParameterPair aMap; 3450 if ( rPropVal.Value >>= aMap ) 3451 { 3452 if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aMap.First ) ) 3453 nFlags |= 0x800; 3454 if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aMap.Second ) ) 3455 nFlags |= 0x1000; 3456 nFlags |= 0x10; 3457 } 3458 } 3459 */ 3460 else if ( rPropVal.Name.equals( sRadiusRangeMinimum ) ) 3461 { 3462 nYRangeMin = (sal_Int32)0xff4c0000; // the range of angles seems to be a not 3463 nYRangeMax = (sal_Int32)0x00b40000; // used feature, so we are defaulting this 3464 3465 com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum; 3466 if ( rPropVal.Value >>= aRadiusRangeMinimum ) 3467 { 3468 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin, aRadiusRangeMinimum ) ) 3469 nFlags |= 0x80; 3470 nFlags |= 0x2000; 3471 } 3472 } 3473 else if ( rPropVal.Name.equals( sRadiusRangeMaximum ) ) 3474 { 3475 nYRangeMin = (sal_Int32)0xff4c0000; // the range of angles seems to be a not 3476 nYRangeMax = (sal_Int32)0x00b40000; // used feature, so we are defaulting this 3477 3478 com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum; 3479 if ( rPropVal.Value >>= aRadiusRangeMaximum ) 3480 { 3481 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax, aRadiusRangeMaximum ) ) 3482 nFlags |= 0x100; 3483 nFlags |= 0x2000; 3484 } 3485 } 3486 else if ( rPropVal.Name.equals( sRangeXMinimum ) ) 3487 { 3488 com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMinimum; 3489 if ( rPropVal.Value >>= aXRangeMinimum ) 3490 { 3491 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin, aXRangeMinimum ) ) 3492 nFlags |= 0x80; 3493 nFlags |= 0x20; 3494 } 3495 } 3496 else if ( rPropVal.Name.equals( sRangeXMaximum ) ) 3497 { 3498 com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMaximum; 3499 if ( rPropVal.Value >>= aXRangeMaximum ) 3500 { 3501 if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax, aXRangeMaximum ) ) 3502 nFlags |= 0x100; 3503 nFlags |= 0x20; 3504 } 3505 } 3506 else if ( rPropVal.Name.equals( sRangeYMinimum ) ) 3507 { 3508 com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMinimum; 3509 if ( rPropVal.Value >>= aYRangeMinimum ) 3510 { 3511 if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMin, aYRangeMinimum ) ) 3512 nFlags |= 0x200; 3513 nFlags |= 0x20; 3514 } 3515 } 3516 else if ( rPropVal.Name.equals( sRangeYMaximum ) ) 3517 { 3518 com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMaximum; 3519 if ( rPropVal.Value >>= aYRangeMaximum ) 3520 { 3521 if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMax, aYRangeMaximum ) ) 3522 nFlags |= 0x400; 3523 nFlags |= 0x20; 3524 } 3525 } 3526 } 3527 aOut << nFlags 3528 << nXPosition 3529 << nYPosition 3530 << nXMap 3531 << nYMap 3532 << nXRangeMin 3533 << nXRangeMax 3534 << nYRangeMin 3535 << nYRangeMax; 3536 3537 if ( nFlags & 8 ) 3538 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << ( nYPosition - 0x100 ) ); 3539 } 3540 sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ]; 3541 memcpy( pBuf, aOut.GetData(), nStreamSize ); 3542 AddOpt( DFF_Prop_Handles, sal_True, nStreamSize - 6, pBuf, nStreamSize ); 3543 } 3544 else 3545 { 3546 sal_uInt8* pBuf = new sal_uInt8[ 1 ]; 3547 AddOpt( DFF_Prop_Handles, sal_True, 0, pBuf, 0 ); 3548 } 3549 } 3550 } 3551 } 3552 else if ( rProp.Name.equals( sAdjustmentValues ) ) 3553 { 3554 // it is required, that the information which handle is polar has already be read, 3555 // so we are able to change the polar value to a fixed float 3556 pAdjustmentValuesProp = &rProp; 3557 } 3558 } 3559 if ( pAdjustmentValuesProp ) 3560 { 3561 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq; 3562 if ( pAdjustmentValuesProp->Value >>= aAdjustmentSeq ) 3563 { 3564 if ( bPredefinedHandlesUsed ) 3565 LookForPolarHandles( eShapeType, nAdjustmentsWhichNeedsToBeConverted ); 3566 3567 sal_Int32 k, nValue = 0, nAdjustmentValues = aAdjustmentSeq.getLength(); 3568 for ( k = 0; k < nAdjustmentValues; k++ ) 3569 if( GetAdjustmentValue( aAdjustmentSeq[ k ], k, nAdjustmentsWhichNeedsToBeConverted, nValue ) ) 3570 AddOpt( (sal_uInt16)( DFF_Prop_adjustValue + k ), (sal_uInt32)nValue ); 3571 } 3572 } 3573 if( pPathCoordinatesProp ) 3574 { 3575 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates; 3576 if ( pPathCoordinatesProp->Value >>= aCoordinates ) 3577 { 3578 // creating the vertices 3579 if ( (sal_uInt16)aCoordinates.getLength() ) 3580 { 3581 sal_uInt16 j, nElements = (sal_uInt16)aCoordinates.getLength(); 3582 sal_uInt16 nElementSize = 8; 3583 sal_uInt32 nStreamSize = nElementSize * nElements + 6; 3584 SvMemoryStream aOut( nStreamSize ); 3585 aOut << nElements 3586 << nElements 3587 << nElementSize; 3588 for( j = 0; j < nElements; j++ ) 3589 { 3590 sal_Int32 X = GetValueForEnhancedCustomShapeParameter( aCoordinates[ j ].First, aEquationOrder, sal_True ); 3591 sal_Int32 Y = GetValueForEnhancedCustomShapeParameter( aCoordinates[ j ].Second, aEquationOrder, sal_True ); 3592 aOut << X 3593 << Y; 3594 } 3595 sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ]; 3596 memcpy( pBuf, aOut.GetData(), nStreamSize ); 3597 AddOpt( DFF_Prop_pVertices, sal_True, nStreamSize - 6, pBuf, nStreamSize ); // -6 3598 } 3599 else 3600 { 3601 sal_uInt8* pBuf = new sal_uInt8[ 1 ]; 3602 AddOpt( DFF_Prop_pVertices, sal_True, 0, pBuf, 0 ); 3603 } 3604 } 3605 } 3606 } 3607 } 3608 } 3609 3610 // --------------------------------------------------------------------------------------------- 3611 3612 MSO_SPT EscherPropertyContainer::GetCustomShapeType( const uno::Reference< drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags, rtl::OUString& rShapeType ) 3613 { 3614 MSO_SPT eShapeType = mso_sptNil; 3615 nMirrorFlags = 0; 3616 uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY ); 3617 if ( aXPropSet.is() ) 3618 { 3619 try 3620 { 3621 const OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM ( "CustomShapeGeometry" ) ); 3622 uno::Any aGeoPropSet = aXPropSet->getPropertyValue( sCustomShapeGeometry ); 3623 uno::Sequence< beans::PropertyValue > aGeoPropSeq; 3624 if ( aGeoPropSet >>= aGeoPropSeq ) 3625 { 3626 sal_Int32 i, nCount = aGeoPropSeq.getLength(); 3627 for ( i = 0; i < nCount; i++ ) 3628 { 3629 const beans::PropertyValue& rProp = aGeoPropSeq[ i ]; 3630 if ( rProp.Name.equalsAscii( "Type" ) ) 3631 { 3632 if ( rProp.Value >>= rShapeType ) 3633 eShapeType = EnhancedCustomShapeTypeNames::Get( rShapeType ); 3634 } 3635 else if ( rProp.Name.equalsAscii( "MirroredX" ) ) 3636 { 3637 sal_Bool bMirroredX = sal_Bool(); 3638 if ( ( rProp.Value >>= bMirroredX ) && bMirroredX ) 3639 nMirrorFlags |= SHAPEFLAG_FLIPH; 3640 } 3641 else if ( rProp.Name.equalsAscii( "MirroredY" ) ) 3642 { 3643 sal_Bool bMirroredY = sal_Bool(); 3644 if ( ( rProp.Value >>= bMirroredY ) && bMirroredY ) 3645 nMirrorFlags |= SHAPEFLAG_FLIPV; 3646 } 3647 } 3648 } 3649 } 3650 catch( ::com::sun::star::uno::Exception& ) 3651 { 3652 } 3653 } 3654 return eShapeType; 3655 } 3656 3657 MSO_SPT EscherPropertyContainer::GetCustomShapeType( const uno::Reference< drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags ) 3658 { 3659 rtl::OUString aShapeType; 3660 return GetCustomShapeType( rXShape, nMirrorFlags, aShapeType ); 3661 } 3662 3663 // --------------------------------------------------------------------------------------------- 3664 3665 EscherPersistTable::EscherPersistTable() 3666 { 3667 } 3668 3669 // --------------------------------------------------------------------------------------------- 3670 3671 EscherPersistTable::~EscherPersistTable() 3672 { 3673 for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() ) 3674 delete (EscherPersistEntry*)pPtr; 3675 } 3676 3677 // --------------------------------------------------------------------------------------------- 3678 3679 sal_Bool EscherPersistTable::PtIsID( sal_uInt32 nID ) 3680 { 3681 for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() ) 3682 { 3683 if ( ((EscherPersistEntry*)pPtr)->mnID == nID ) 3684 return sal_True; 3685 } 3686 return sal_False; 3687 } 3688 3689 // --------------------------------------------------------------------------------------------- 3690 3691 void EscherPersistTable::PtInsert( sal_uInt32 nID, sal_uInt32 nOfs ) 3692 { 3693 maPersistTable.Insert( new EscherPersistEntry( nID, nOfs ) ); 3694 } 3695 3696 // --------------------------------------------------------------------------------------------- 3697 3698 sal_uInt32 EscherPersistTable::PtDelete( sal_uInt32 nID ) 3699 { 3700 for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() ) 3701 { 3702 if ( ((EscherPersistEntry*)pPtr)->mnID == nID ) 3703 { 3704 // sal_uInt32 nRetValue = ((EscherPersistEntry*)pPtr)->mnOffset; 3705 delete (EscherPersistEntry*) maPersistTable.Remove(); 3706 } 3707 } 3708 return 0; 3709 } 3710 3711 // --------------------------------------------------------------------------------------------- 3712 3713 sal_uInt32 EscherPersistTable::PtGetOffsetByID( sal_uInt32 nID ) 3714 { 3715 for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() ) 3716 { 3717 if ( ((EscherPersistEntry*)pPtr)->mnID == nID ) 3718 return ((EscherPersistEntry*)pPtr)->mnOffset; 3719 } 3720 return 0; 3721 }; 3722 3723 // --------------------------------------------------------------------------------------------- 3724 3725 sal_uInt32 EscherPersistTable::PtReplace( sal_uInt32 nID, sal_uInt32 nOfs ) 3726 { 3727 for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() ) 3728 { 3729 if ( ((EscherPersistEntry*)pPtr)->mnID == nID ) 3730 { 3731 sal_uInt32 nRetValue = ((EscherPersistEntry*)pPtr)->mnOffset; 3732 ((EscherPersistEntry*)pPtr)->mnOffset = nOfs; 3733 return nRetValue; 3734 } 3735 } 3736 return 0; 3737 } 3738 3739 // --------------------------------------------------------------------------------------------- 3740 3741 sal_uInt32 EscherPersistTable::PtReplaceOrInsert( sal_uInt32 nID, sal_uInt32 nOfs ) 3742 { 3743 for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() ) 3744 { 3745 if ( ((EscherPersistEntry*)pPtr)->mnID == nID ) 3746 { 3747 sal_uInt32 nRetValue = ((EscherPersistEntry*)pPtr)->mnOffset; 3748 ((EscherPersistEntry*)pPtr)->mnOffset = nOfs; 3749 return nRetValue; 3750 } 3751 } 3752 PtInsert( nID, nOfs ); 3753 return 0; 3754 } 3755 3756 sal_Bool EscherPropertyValueHelper::GetPropertyValue( 3757 ::com::sun::star::uno::Any& rAny, 3758 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 3759 const String& rString, 3760 sal_Bool bTestPropertyAvailability ) 3761 { 3762 sal_Bool bRetValue = sal_True; 3763 if ( bTestPropertyAvailability ) 3764 { 3765 bRetValue = sal_False; 3766 try 3767 { 3768 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > 3769 aXPropSetInfo( rXPropSet->getPropertySetInfo() ); 3770 if ( aXPropSetInfo.is() ) 3771 bRetValue = aXPropSetInfo->hasPropertyByName( rString ); 3772 } 3773 catch( ::com::sun::star::uno::Exception& ) 3774 { 3775 bRetValue = sal_False; 3776 } 3777 } 3778 if ( bRetValue ) 3779 { 3780 try 3781 { 3782 rAny = rXPropSet->getPropertyValue( rString ); 3783 if ( !rAny.hasValue() ) 3784 bRetValue = sal_False; 3785 } 3786 catch( ::com::sun::star::uno::Exception& ) 3787 { 3788 bRetValue = sal_False; 3789 } 3790 } 3791 return bRetValue; 3792 } 3793 3794 // --------------------------------------------------------------------------------------------- 3795 3796 ::com::sun::star::beans::PropertyState EscherPropertyValueHelper::GetPropertyState( 3797 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 3798 const String& rPropertyName ) 3799 { 3800 ::com::sun::star::beans::PropertyState eRetValue = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE; 3801 try 3802 { 3803 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > aXPropState 3804 ( rXPropSet, ::com::sun::star::uno::UNO_QUERY ); 3805 if ( aXPropState.is() ) 3806 eRetValue = aXPropState->getPropertyState( rPropertyName ); 3807 } 3808 catch( ::com::sun::star::uno::Exception& ) 3809 { 3810 //... 3811 } 3812 return eRetValue; 3813 } 3814 3815 // --------------------------------------------------------------------------------------------- 3816 // --------------------------------------------------------------------------------------------- 3817 // --------------------------------------------------------------------------------------------- 3818 3819 EscherBlibEntry::EscherBlibEntry( sal_uInt32 nPictureOffset, const GraphicObject& rObject, const ByteString& rId, 3820 const GraphicAttr* pGraphicAttr ) : 3821 mnPictureOffset ( nPictureOffset ), 3822 mnRefCount ( 1 ), 3823 mnSizeExtra ( 0 ), 3824 maPrefSize ( rObject.GetPrefSize() ), 3825 maPrefMapMode ( rObject.GetPrefMapMode() ), 3826 mbIsEmpty ( sal_True ) 3827 { 3828 mbIsNativeGraphicPossible = ( pGraphicAttr == NULL ); 3829 meBlibType = UNKNOWN; 3830 mnSize = 0; 3831 3832 sal_uInt32 nLen = rId.Len(); 3833 const sal_Char* pData = rId.GetBuffer(); 3834 GraphicType eType( rObject.GetType() ); 3835 if ( nLen && pData && ( eType != GRAPHIC_NONE ) ) 3836 { 3837 mnIdentifier[ 0 ] = rtl_crc32( 0,pData, nLen ); 3838 mnIdentifier[ 1 ] = 0; 3839 3840 if ( pGraphicAttr ) 3841 { 3842 if ( pGraphicAttr->IsSpecialDrawMode() 3843 || pGraphicAttr->IsMirrored() 3844 || pGraphicAttr->IsCropped() 3845 || pGraphicAttr->IsRotated() 3846 || pGraphicAttr->IsTransparent() 3847 || pGraphicAttr->IsAdjusted() ) 3848 { 3849 SvMemoryStream aSt( sizeof( GraphicAttr ) ); 3850 aSt << static_cast<sal_uInt16>(pGraphicAttr->GetDrawMode()) 3851 << static_cast<sal_uInt32>(pGraphicAttr->GetMirrorFlags()) 3852 << pGraphicAttr->GetLeftCrop() 3853 << pGraphicAttr->GetTopCrop() 3854 << pGraphicAttr->GetRightCrop() 3855 << pGraphicAttr->GetBottomCrop() 3856 << pGraphicAttr->GetRotation() 3857 << pGraphicAttr->GetLuminance() 3858 << pGraphicAttr->GetContrast() 3859 << pGraphicAttr->GetChannelR() 3860 << pGraphicAttr->GetChannelG() 3861 << pGraphicAttr->GetChannelB() 3862 << pGraphicAttr->GetGamma() 3863 << (sal_Bool)( pGraphicAttr->IsInvert() == sal_True ) 3864 << pGraphicAttr->GetTransparency(); 3865 mnIdentifier[ 1 ] = rtl_crc32( 0, aSt.GetData(), aSt.Tell() ); 3866 } 3867 else 3868 mbIsNativeGraphicPossible = sal_True; 3869 } 3870 sal_uInt32 i, nTmp, n1, n2; 3871 n1 = n2 = 0; 3872 for ( i = 0; i < nLen; i++ ) 3873 { 3874 nTmp = n2 >> 28; // rotating 4 bit 3875 n2 <<= 4; 3876 n2 |= n1 >> 28; 3877 n1 <<= 4; 3878 n1 |= nTmp; 3879 n1 ^= *pData++ - '0'; 3880 } 3881 mnIdentifier[ 2 ] = n1; 3882 mnIdentifier[ 3 ] = n2; 3883 mbIsEmpty = sal_False; 3884 } 3885 }; 3886 3887 // --------------------------------------------------------------------------------------------- 3888 3889 void EscherBlibEntry::WriteBlibEntry( SvStream& rSt, sal_Bool bWritePictureOffset, sal_uInt32 nResize ) 3890 { 3891 sal_uInt32 nPictureOffset = ( bWritePictureOffset ) ? mnPictureOffset : 0; 3892 3893 rSt << (sal_uInt32)( ( ESCHER_BSE << 16 ) | ( ( (sal_uInt16)meBlibType << 4 ) | 2 ) ) 3894 << (sal_uInt32)( 36 + nResize ) 3895 << (sal_uInt8)meBlibType; 3896 3897 switch ( meBlibType ) 3898 { 3899 case EMF : 3900 case WMF : // EMF/WMF auf OS2 zu Pict Konvertieren 3901 rSt << (sal_uInt8)PICT; 3902 break; 3903 default: 3904 rSt << (sal_uInt8)meBlibType; 3905 }; 3906 3907 rSt.Write( &mnIdentifier[ 0 ], 16 ); 3908 rSt << (sal_uInt16)0 3909 << (sal_uInt32)( mnSize + mnSizeExtra ) 3910 << mnRefCount 3911 << nPictureOffset 3912 << (sal_uInt32)0; 3913 } 3914 3915 // --------------------------------------------------------------------------------------------- 3916 3917 EscherBlibEntry::~EscherBlibEntry() 3918 { 3919 }; 3920 3921 // --------------------------------------------------------------------------------------------- 3922 3923 sal_Bool EscherBlibEntry::operator==( const EscherBlibEntry& rEscherBlibEntry ) const 3924 { 3925 for ( int i = 0; i < 3; i++ ) 3926 { 3927 if ( mnIdentifier[ i ] != rEscherBlibEntry.mnIdentifier[ i ] ) 3928 return sal_False; 3929 } 3930 return sal_True; 3931 } 3932 3933 // --------------------------------------------------------------------------------------------- 3934 // --------------------------------------------------------------------------------------------- 3935 // --------------------------------------------------------------------------------------------- 3936 3937 EscherGraphicProvider::EscherGraphicProvider( sal_uInt32 nFlags ) : 3938 mnFlags ( nFlags ), 3939 mpBlibEntrys ( NULL ), 3940 mnBlibBufSize ( 0 ), 3941 mnBlibEntrys ( 0 ) 3942 { 3943 } 3944 3945 EscherGraphicProvider::~EscherGraphicProvider() 3946 { 3947 for ( sal_uInt32 i = 0; i < mnBlibEntrys; delete mpBlibEntrys[ i++ ] ) ; 3948 delete[] mpBlibEntrys; 3949 } 3950 3951 void EscherGraphicProvider::SetNewBlipStreamOffset( sal_Int32 nOffset ) 3952 { 3953 for( sal_uInt32 i = 0; i < mnBlibEntrys; i++ ) 3954 { 3955 EscherBlibEntry* pBlibEntry = mpBlibEntrys[ i ]; 3956 pBlibEntry->mnPictureOffset += nOffset; 3957 } 3958 } 3959 3960 sal_uInt32 EscherGraphicProvider::ImplInsertBlib( EscherBlibEntry* p_EscherBlibEntry ) 3961 { 3962 if ( mnBlibBufSize == mnBlibEntrys ) 3963 { 3964 mnBlibBufSize += 64; 3965 EscherBlibEntry** pTemp = new EscherBlibEntry*[ mnBlibBufSize ]; 3966 for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ ) 3967 { 3968 pTemp[ i ] = mpBlibEntrys[ i ]; 3969 } 3970 delete[] mpBlibEntrys; 3971 mpBlibEntrys = pTemp; 3972 } 3973 mpBlibEntrys[ mnBlibEntrys++ ] = p_EscherBlibEntry; 3974 return mnBlibEntrys; 3975 } 3976 3977 sal_uInt32 EscherGraphicProvider::GetBlibStoreContainerSize( SvStream* pMergePicStreamBSE ) const 3978 { 3979 sal_uInt32 nSize = 44 * mnBlibEntrys + 8; 3980 if ( pMergePicStreamBSE ) 3981 { 3982 for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ ) 3983 nSize += mpBlibEntrys[ i ]->mnSize + mpBlibEntrys[ i ]->mnSizeExtra; 3984 } 3985 return nSize; 3986 } 3987 3988 sal_Bool EscherGraphicProvider::WriteBlibStoreEntry(SvStream& rSt, 3989 sal_uInt32 nBlipId, sal_Bool bWritePictureOffSet, sal_uInt32 nResize) 3990 { 3991 if (nBlipId > mnBlibEntrys || nBlipId == 0) 3992 return sal_False; 3993 mpBlibEntrys[nBlipId-1]->WriteBlibEntry(rSt, bWritePictureOffSet, nResize); 3994 return sal_True; 3995 } 3996 3997 void EscherGraphicProvider::WriteBlibStoreContainer( SvStream& rSt, SvStream* pMergePicStreamBSE ) 3998 { 3999 sal_uInt32 nSize = GetBlibStoreContainerSize( pMergePicStreamBSE ); 4000 if ( nSize ) 4001 { 4002 rSt << (sal_uInt32)( ( ESCHER_BstoreContainer << 16 ) | 0x1f ) 4003 << (sal_uInt32)( nSize - 8 ); 4004 4005 if ( pMergePicStreamBSE ) 4006 { 4007 sal_uInt32 i, nBlipSize, nOldPos = pMergePicStreamBSE->Tell(); 4008 const sal_uInt32 nBuf = 0x40000; // 256KB buffer 4009 sal_uInt8* pBuf = new sal_uInt8[ nBuf ]; 4010 4011 for ( i = 0; i < mnBlibEntrys; i++ ) 4012 { 4013 EscherBlibEntry* pBlibEntry = mpBlibEntrys[ i ]; 4014 4015 ESCHER_BlibType nBlibType = pBlibEntry->meBlibType; 4016 nBlipSize = pBlibEntry->mnSize + pBlibEntry->mnSizeExtra; 4017 pBlibEntry->WriteBlibEntry( rSt, sal_False, nBlipSize ); 4018 4019 // BLIP 4020 pMergePicStreamBSE->Seek( pBlibEntry->mnPictureOffset ); 4021 sal_uInt16 n16; 4022 // record version and instance 4023 *pMergePicStreamBSE >> n16; 4024 rSt << n16; 4025 // record type 4026 *pMergePicStreamBSE >> n16; 4027 rSt << sal_uInt16( ESCHER_BlipFirst + nBlibType ); 4028 DBG_ASSERT( n16 == ESCHER_BlipFirst + nBlibType , "EscherGraphicProvider::WriteBlibStoreContainer: BLIP record types differ" ); 4029 sal_uInt32 n32; 4030 // record size 4031 *pMergePicStreamBSE >> n32; 4032 nBlipSize -= 8; 4033 rSt << nBlipSize; 4034 DBG_ASSERT( nBlipSize == n32, "EscherGraphicProvider::WriteBlibStoreContainer: BLIP sizes differ" ); 4035 // record 4036 while ( nBlipSize ) 4037 { 4038 sal_uInt32 nBytes = ( nBlipSize > nBuf ? nBuf : nBlipSize ); 4039 pMergePicStreamBSE->Read( pBuf, nBytes ); 4040 rSt.Write( pBuf, nBytes ); 4041 nBlipSize -= nBytes; 4042 } 4043 } 4044 delete[] pBuf; 4045 pMergePicStreamBSE->Seek( nOldPos ); 4046 } 4047 else 4048 { 4049 for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ ) 4050 mpBlibEntrys[ i ]->WriteBlibEntry( rSt, sal_True ); 4051 } 4052 } 4053 } 4054 4055 sal_Bool EscherGraphicProvider::GetPrefSize( const sal_uInt32 nBlibId, Size& rPrefSize, MapMode& rPrefMapMode ) 4056 { 4057 sal_Bool bInRange = nBlibId && ( ( nBlibId - 1 ) < mnBlibEntrys ); 4058 if ( bInRange ) 4059 { 4060 EscherBlibEntry* pEntry = mpBlibEntrys[ nBlibId - 1 ]; 4061 rPrefSize = pEntry->maPrefSize; 4062 rPrefMapMode = pEntry->maPrefMapMode; 4063 } 4064 return bInRange; 4065 } 4066 4067 sal_uInt32 EscherGraphicProvider::GetBlibID( SvStream& rPicOutStrm, const ByteString& rId, 4068 const Rectangle& /* rBoundRect */, const com::sun::star::awt::Rectangle* pVisArea, const GraphicAttr* pGraphicAttr ) 4069 { 4070 sal_uInt32 nBlibId = 0; 4071 GraphicObject aGraphicObject( rId ); 4072 4073 EscherBlibEntry* p_EscherBlibEntry = new EscherBlibEntry( rPicOutStrm.Tell(), aGraphicObject, rId, pGraphicAttr ); 4074 if ( !p_EscherBlibEntry->IsEmpty() ) 4075 { 4076 for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ ) 4077 { 4078 if ( *( mpBlibEntrys[ i ] ) == *p_EscherBlibEntry ) 4079 { 4080 mpBlibEntrys[ i ]->mnRefCount++; 4081 delete p_EscherBlibEntry; 4082 return i + 1; 4083 } 4084 } 4085 4086 sal_Bool bUseNativeGraphic( sal_False ); 4087 4088 Graphic aGraphic( aGraphicObject.GetTransformedGraphic( pGraphicAttr ) ); 4089 GfxLink aGraphicLink; 4090 SvMemoryStream aStream; 4091 4092 const sal_uInt8* pGraphicAry = NULL; 4093 4094 if ( p_EscherBlibEntry->mbIsNativeGraphicPossible && aGraphic.IsLink() ) 4095 { 4096 aGraphicLink = aGraphic.GetLink(); 4097 4098 p_EscherBlibEntry->mnSize = aGraphicLink.GetDataSize(); 4099 pGraphicAry = aGraphicLink.GetData(); 4100 4101 if ( p_EscherBlibEntry->mnSize && pGraphicAry ) 4102 { 4103 switch ( aGraphicLink.GetType() ) 4104 { 4105 case GFX_LINK_TYPE_NATIVE_JPG : p_EscherBlibEntry->meBlibType = PEG; break; 4106 case GFX_LINK_TYPE_NATIVE_PNG : p_EscherBlibEntry->meBlibType = PNG; break; 4107 case GFX_LINK_TYPE_NATIVE_WMF : 4108 { 4109 if ( pGraphicAry && ( p_EscherBlibEntry->mnSize > 0x2c ) ) 4110 { 4111 if ( ( pGraphicAry[ 0x28 ] == 0x20 ) && ( pGraphicAry[ 0x29 ] == 0x45 ) // check the magic 4112 && ( pGraphicAry[ 0x2a ] == 0x4d ) && ( pGraphicAry[ 0x2b ] == 0x46 ) ) // number ( emf detection ) 4113 { 4114 p_EscherBlibEntry->meBlibType = EMF; 4115 } 4116 else 4117 { 4118 p_EscherBlibEntry->meBlibType = WMF; 4119 if ( ( pGraphicAry[ 0 ] == 0xd7 ) && ( pGraphicAry[ 1 ] == 0xcd ) 4120 && ( pGraphicAry[ 2 ] == 0xc6 ) && ( pGraphicAry[ 3 ] == 0x9a ) ) 4121 { // we have to get rid of the metafileheader 4122 pGraphicAry += 22; 4123 p_EscherBlibEntry->mnSize -= 22; 4124 } 4125 } 4126 } 4127 } 4128 break; 4129 default: break; 4130 } 4131 if ( p_EscherBlibEntry->meBlibType != UNKNOWN ) 4132 bUseNativeGraphic = sal_True; 4133 } 4134 } 4135 if ( !bUseNativeGraphic ) 4136 { 4137 GraphicType eGraphicType = aGraphic.GetType(); 4138 if ( ( eGraphicType == GRAPHIC_BITMAP ) || ( eGraphicType == GRAPHIC_GDIMETAFILE ) ) 4139 { 4140 sal_uInt32 nErrCode; 4141 if ( !aGraphic.IsAnimated() ) 4142 // !EMF nErrCode = GraphicConverter::Export( aStream, aGraphic, ( eGraphicType == GRAPHIC_BITMAP ) ? CVT_PNG : CVT_WMF ); 4143 nErrCode = GraphicConverter::Export( aStream, aGraphic, ( eGraphicType == GRAPHIC_BITMAP ) ? CVT_PNG : CVT_EMF ); 4144 else 4145 { // to store a animation, a gif has to be included into the msOG chunk of a png #I5583# 4146 GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); 4147 SvMemoryStream aGIFStream; 4148 ByteString aVersion( "MSOFFICE9.0" ); 4149 aGIFStream.Write( aVersion.GetBuffer(), aVersion.Len() ); 4150 nErrCode = pFilter->ExportGraphic( aGraphic, String(), aGIFStream, 4151 pFilter->GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "GIF" ) ) ), NULL ); 4152 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aFilterData( 1 ); 4153 com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence( 1 ); 4154 sal_uInt32 nGIFSreamLen = aGIFStream.Tell(); 4155 com::sun::star::uno::Sequence< sal_Int8 > aGIFSeq( nGIFSreamLen ); 4156 sal_Int8* pSeq = aGIFSeq.getArray(); 4157 aGIFStream.Seek( STREAM_SEEK_TO_BEGIN ); 4158 aGIFStream.Read( pSeq, nGIFSreamLen ); 4159 com::sun::star::beans::PropertyValue aChunkProp, aFilterProp; 4160 aChunkProp.Name = String( RTL_CONSTASCII_USTRINGPARAM( "msOG" ) ); 4161 aChunkProp.Value <<= aGIFSeq; 4162 aAdditionalChunkSequence[ 0 ] = aChunkProp; 4163 aFilterProp.Name = String( RTL_CONSTASCII_USTRINGPARAM( "AdditionalChunks" ) ); 4164 aFilterProp.Value <<= aAdditionalChunkSequence; 4165 aFilterData[ 0 ] = aFilterProp; 4166 nErrCode = pFilter->ExportGraphic( aGraphic, String(), aStream, 4167 pFilter->GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) ) ), &aFilterData ); 4168 } 4169 if ( nErrCode == ERRCODE_NONE ) 4170 { 4171 // !EMF p_EscherBlibEntry->meBlibType = ( eGraphicType == GRAPHIC_BITMAP ) ? PNG : WMF; 4172 p_EscherBlibEntry->meBlibType = ( eGraphicType == GRAPHIC_BITMAP ) ? PNG : EMF; 4173 aStream.Seek( STREAM_SEEK_TO_END ); 4174 p_EscherBlibEntry->mnSize = aStream.Tell(); 4175 pGraphicAry = (sal_uInt8*)aStream.GetData(); 4176 4177 if ( p_EscherBlibEntry->meBlibType == WMF ) // the fileheader is not used 4178 { 4179 p_EscherBlibEntry->mnSize -= 22; 4180 pGraphicAry += 22; 4181 } 4182 } 4183 } 4184 } 4185 4186 ESCHER_BlibType eBlibType = p_EscherBlibEntry->meBlibType; 4187 if ( p_EscherBlibEntry->mnSize && pGraphicAry && ( eBlibType != UNKNOWN ) ) 4188 { 4189 sal_uInt32 nExtra, nAtomSize = 0; 4190 sal_uInt32 nInstance, nUncompressedSize = p_EscherBlibEntry->mnSize; 4191 4192 if ( mnFlags & _E_GRAPH_PROV_USE_INSTANCES ) 4193 { 4194 rPicOutStrm << (sal_uInt32)( 0x7f90000 | (sal_uInt16)( mnBlibEntrys << 4 ) ) 4195 << (sal_uInt32)0; 4196 nAtomSize = rPicOutStrm.Tell(); 4197 if ( eBlibType == PNG ) 4198 rPicOutStrm << (sal_uInt16)0x0606; 4199 else if ( eBlibType == WMF ) 4200 rPicOutStrm << (sal_uInt16)0x0403; 4201 else if ( eBlibType == EMF ) 4202 rPicOutStrm << (sal_uInt16)0x0402; 4203 else if ( eBlibType == PEG ) 4204 rPicOutStrm << (sal_uInt16)0x0505; 4205 } 4206 if ( ( eBlibType == PEG ) || ( eBlibType == PNG ) ) 4207 { 4208 nExtra = 17; 4209 p_EscherBlibEntry->mnSizeExtra = nExtra + 8; 4210 nInstance = ( eBlibType == PNG ) ? 0xf01e6e00 : 0xf01d46a0; 4211 rPicOutStrm << nInstance << (sal_uInt32)( p_EscherBlibEntry->mnSize + nExtra ); 4212 rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 ); 4213 rPicOutStrm << (sal_uInt8)0xff; 4214 rPicOutStrm.Write( pGraphicAry, p_EscherBlibEntry->mnSize ); 4215 } 4216 else 4217 { 4218 ZCodec aZCodec( 0x8000, 0x8000 ); 4219 aZCodec.BeginCompression(); 4220 SvMemoryStream aDestStrm; 4221 aZCodec.Write( aDestStrm, pGraphicAry, p_EscherBlibEntry->mnSize ); 4222 aZCodec.EndCompression(); 4223 aDestStrm.Seek( STREAM_SEEK_TO_END ); 4224 p_EscherBlibEntry->mnSize = aDestStrm.Tell(); 4225 pGraphicAry = (sal_uInt8*)aDestStrm.GetData(); 4226 if ( p_EscherBlibEntry->mnSize && pGraphicAry ) 4227 { 4228 nExtra = eBlibType == WMF ? 0x42 : 0x32; // !EMF -> no change 4229 p_EscherBlibEntry->mnSizeExtra = nExtra + 8; 4230 nInstance = ( eBlibType == WMF ) ? 0xf01b2170 : 0xf01a3d40; // !EMF -> no change 4231 rPicOutStrm << nInstance << (sal_uInt32)( p_EscherBlibEntry->mnSize + nExtra ); 4232 if ( eBlibType == WMF ) // !EMF -> no change 4233 rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 ); 4234 rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 ); 4235 4236 /* 4237 ##913## 4238 For Word the stored size of the graphic is critical the 4239 metafile boundaries must match the actual graphics 4240 boundaries, and the width and height must be in EMU's 4241 4242 If you don't do it this way then objects edited in the 4243 msoffice app may show strange behaviour as the size jumps 4244 around, and the original size and scaling factor in word 4245 will be a very strange figure 4246 */ 4247 sal_uInt32 nPrefWidth = p_EscherBlibEntry->maPrefSize.Width(); 4248 sal_uInt32 nPrefHeight = p_EscherBlibEntry->maPrefSize.Height(); 4249 sal_uInt32 nWidth, nHeight; 4250 if ( pVisArea ) 4251 { 4252 nWidth = pVisArea->Width * 360; 4253 nHeight = pVisArea->Height * 360; 4254 } 4255 else 4256 { 4257 Size aPrefSize(lcl_SizeToEmu(p_EscherBlibEntry->maPrefSize, p_EscherBlibEntry->maPrefMapMode)); 4258 nWidth = aPrefSize.Width() * 360; 4259 nHeight = aPrefSize.Height() * 360; 4260 } 4261 rPicOutStrm << nUncompressedSize // WMFSize without FileHeader 4262 << (sal_Int32)0 // da die Originalgroesse des WMF's (ohne FileHeader) 4263 << (sal_Int32)0 // nicht mehr feststellbar ist, schreiben wir 10cm / x 4264 << nPrefWidth 4265 << nPrefHeight 4266 << nWidth 4267 << nHeight 4268 << p_EscherBlibEntry->mnSize 4269 << (sal_uInt16)0xfe00; // compression Flags 4270 rPicOutStrm.Write( pGraphicAry, p_EscherBlibEntry->mnSize ); 4271 } 4272 } 4273 if ( nAtomSize ) 4274 { 4275 sal_uInt32 nPos = rPicOutStrm.Tell(); 4276 rPicOutStrm.Seek( nAtomSize - 4 ); 4277 rPicOutStrm << (sal_uInt32)( nPos - nAtomSize ); 4278 rPicOutStrm.Seek( nPos ); 4279 } 4280 nBlibId = ImplInsertBlib( p_EscherBlibEntry ), p_EscherBlibEntry = NULL; 4281 } 4282 } 4283 if ( p_EscherBlibEntry ) 4284 delete p_EscherBlibEntry; 4285 return nBlibId; 4286 } 4287 4288 // --------------------------------------------------------------------------------------------- 4289 // --------------------------------------------------------------------------------------------- 4290 // --------------------------------------------------------------------------------------------- 4291 4292 struct EscherConnectorRule 4293 { 4294 sal_uInt32 nRuleId; 4295 sal_uInt32 nShapeA; // SPID of shape A 4296 sal_uInt32 nShapeB; // SPID of shape B 4297 sal_uInt32 nShapeC; // SPID of connector shape 4298 sal_uInt32 ncptiA; // Connection site Index of shape A 4299 sal_uInt32 ncptiB; // Connection site Index of shape B 4300 }; 4301 4302 struct EscherShapeListEntry 4303 { 4304 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aXShape; 4305 sal_uInt32 n_EscherId; 4306 4307 EscherShapeListEntry( const ::com::sun::star::uno::Reference 4308 < ::com::sun::star::drawing::XShape > & rShape, sal_uInt32 nId ) : 4309 aXShape ( rShape ), 4310 n_EscherId ( nId ) {} 4311 }; 4312 4313 sal_uInt32 EscherConnectorListEntry::GetClosestPoint( const Polygon& rPoly, const ::com::sun::star::awt::Point& rPoint ) 4314 { 4315 sal_uInt16 nCount = rPoly.GetSize(); 4316 sal_uInt16 nClosest = nCount; 4317 double fDist = (sal_uInt32)0xffffffff; 4318 while( nCount-- ) 4319 { 4320 double fDistance = hypot( rPoint.X - rPoly[ nCount ].X(), rPoint.Y - rPoly[ nCount ].Y() ); 4321 if ( fDistance < fDist ) 4322 { 4323 nClosest = nCount; 4324 fDist = fDistance; 4325 } 4326 } 4327 return nClosest; 4328 }; 4329 4330 // --------------------------------------------------------------------------------------------- 4331 // bei Rechtecken bei Ellipsen bei Polygonen 4332 // 4333 // nRule = 0 ->Top 0 ->Top nRule = Index auf ein (Poly)Polygon Punkt 4334 // 1 ->Left 2 ->Left 4335 // 2 ->Bottom 4 ->Bottom 4336 // 3 ->Right 6 ->Right 4337 4338 sal_uInt32 EscherConnectorListEntry::GetConnectorRule( sal_Bool bFirst ) 4339 { 4340 sal_uInt32 nRule = 0; 4341 4342 ::com::sun::star::uno::Any aAny; 4343 ::com::sun::star::awt::Point aRefPoint( ( bFirst ) ? maPointA : maPointB ); 4344 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > 4345 aXShape( ( bFirst ) ? mXConnectToA : mXConnectToB ); 4346 4347 String aString( (::rtl::OUString)aXShape->getShapeType() ); 4348 ByteString aType( aString, RTL_TEXTENCODING_UTF8 ); 4349 aType.Erase( 0, 13 ); // removing "com.sun.star." 4350 sal_uInt16 nPos = aType.Search( "Shape" ); 4351 aType.Erase( nPos, 5 ); 4352 4353 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > 4354 aPropertySet( aXShape, ::com::sun::star::uno::UNO_QUERY ); 4355 4356 if ( aType == "drawing.PolyPolygon" || aType == "drawing.PolyLine" ) 4357 { 4358 if ( aPropertySet.is() ) 4359 { 4360 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, 4361 aPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) ) ) ) 4362 { 4363 ::com::sun::star::drawing::PointSequenceSequence* pSourcePolyPolygon = 4364 (::com::sun::star::drawing::PointSequenceSequence*)aAny.getValue(); 4365 sal_Int32 nOuterSequenceCount = pSourcePolyPolygon->getLength(); 4366 ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray(); 4367 4368 if ( pOuterSequence ) 4369 { 4370 sal_Int32 a, b, nIndex = 0; 4371 sal_uInt32 nDistance = 0xffffffff; 4372 for( a = 0; a < nOuterSequenceCount; a++ ) 4373 { 4374 ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++; 4375 if ( pInnerSequence ) 4376 { 4377 ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray(); 4378 if ( pArray ) 4379 { 4380 for ( b = 0; b < pInnerSequence->getLength(); b++, nIndex++, pArray++ ) 4381 { 4382 sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - pArray->X, aRefPoint.Y - pArray->Y ); 4383 if ( nDist < nDistance ) 4384 { 4385 nRule = nIndex; 4386 nDistance = nDist; 4387 } 4388 } 4389 } 4390 } 4391 } 4392 } 4393 } 4394 } 4395 } 4396 else if ( ( aType == "drawing.OpenBezier" ) || ( aType == "drawing.OpenFreeHand" ) || ( aType == "drawing.PolyLinePath" ) 4397 || ( aType == "drawing.ClosedBezier" ) || ( aType == "drawing.ClosedFreeHand" ) || ( aType == "drawing.PolyPolygonPath" ) ) 4398 { 4399 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > 4400 aPropertySet2( aXShape, ::com::sun::star::uno::UNO_QUERY ); 4401 if ( aPropertySet2.is() ) 4402 { 4403 if ( EscherPropertyValueHelper::GetPropertyValue( aAny, 4404 aPropertySet2, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) ) ) ) 4405 { 4406 ::com::sun::star::drawing::PolyPolygonBezierCoords* pSourcePolyPolygon = 4407 (::com::sun::star::drawing::PolyPolygonBezierCoords*)aAny.getValue(); 4408 sal_Int32 nOuterSequenceCount = pSourcePolyPolygon->Coordinates.getLength(); 4409 4410 // Zeiger auf innere sequences holen 4411 ::com::sun::star::drawing::PointSequence* pOuterSequence = 4412 pSourcePolyPolygon->Coordinates.getArray(); 4413 ::com::sun::star::drawing::FlagSequence* pOuterFlags = 4414 pSourcePolyPolygon->Flags.getArray(); 4415 4416 if ( pOuterSequence && pOuterFlags ) 4417 { 4418 sal_Int32 a, b, nIndex = 0; 4419 sal_uInt32 nDistance = 0xffffffff; 4420 4421 for ( a = 0; a < nOuterSequenceCount; a++ ) 4422 { 4423 ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++; 4424 ::com::sun::star::drawing::FlagSequence* pInnerFlags = pOuterFlags++; 4425 if ( pInnerSequence && pInnerFlags ) 4426 { 4427 ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray(); 4428 ::com::sun::star::drawing::PolygonFlags* pFlags = pInnerFlags->getArray(); 4429 if ( pArray && pFlags ) 4430 { 4431 for ( b = 0; b < pInnerSequence->getLength(); b++, pArray++ ) 4432 { 4433 PolyFlags ePolyFlags = *( (PolyFlags*)pFlags++ ); 4434 if ( ePolyFlags == POLY_CONTROL ) 4435 continue; 4436 sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - pArray->X, aRefPoint.Y - pArray->Y ); 4437 if ( nDist < nDistance ) 4438 { 4439 nRule = nIndex; 4440 nDistance = nDist; 4441 } 4442 nIndex++; 4443 } 4444 } 4445 } 4446 } 4447 } 4448 } 4449 } 4450 } 4451 else 4452 { 4453 bool bRectangularConnection = true; 4454 4455 if ( aType == "drawing.Custom" ) 4456 { 4457 SdrObject* pCustoShape( GetSdrObjectFromXShape( aXShape ) ); 4458 if ( pCustoShape && pCustoShape->ISA( SdrObjCustomShape ) ) 4459 { 4460 SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&) 4461 pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); 4462 4463 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM( "Path" ) ); 4464 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 4465 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM( "GluePointType" ) ); 4466 4467 rtl::OUString sShapeType; 4468 uno::Any* pType = rGeometryItem.GetPropertyValueByName( sType ); 4469 if ( pType ) 4470 *pType >>= sShapeType; 4471 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType ); 4472 4473 uno::Any* pGluePointType = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sGluePointType ); 4474 4475 sal_Int16 nGluePointType = sal_Int16(); 4476 if ( !( pGluePointType && 4477 ( *pGluePointType >>= nGluePointType ) ) ) 4478 nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType ); 4479 4480 if ( nGluePointType == com::sun::star::drawing::EnhancedCustomShapeGluePointType::CUSTOM ) 4481 { 4482 const SdrGluePointList* pList = pCustoShape->GetGluePointList(); 4483 if ( pList ) 4484 { 4485 Polygon aPoly; 4486 sal_uInt16 nNum, nAnz = pList->GetCount(); 4487 if ( nAnz ) 4488 { 4489 for ( nNum = 0; nNum < nAnz; nNum++ ) 4490 { 4491 const SdrGluePoint& rGP = (*pList)[ nNum ]; 4492 Point aPt( rGP.GetAbsolutePos( *pCustoShape ) ); 4493 aPoly.Insert( POLY_APPEND, aPt ); 4494 } 4495 nRule = GetClosestPoint( aPoly, aRefPoint ); 4496 bRectangularConnection = false; 4497 } 4498 } 4499 } 4500 else if ( nGluePointType == com::sun::star::drawing::EnhancedCustomShapeGluePointType::SEGMENTS ) 4501 { 4502 SdrObject* pPoly = pCustoShape->DoConvertToPolyObj( sal_True, true ); 4503 if ( pPoly && pPoly->ISA( SdrPathObj ) ) 4504 { 4505 sal_Int16 a, b, nIndex = 0; 4506 sal_uInt32 nDistance = 0xffffffff; 4507 4508 // #i74631# use explicit constructor here. Also XPolyPolygon is not necessary, 4509 // reducing to PolyPolygon 4510 const PolyPolygon aPolyPoly(((SdrPathObj*)pPoly)->GetPathPoly()); 4511 4512 for ( a = 0; a < aPolyPoly.Count(); a++ ) 4513 { 4514 const Polygon& rPoly = aPolyPoly.GetObject( a ); 4515 for ( b = 0; b < rPoly.GetSize(); b++ ) 4516 { 4517 if ( rPoly.GetFlags( b ) != POLY_NORMAL ) 4518 continue; 4519 const Point& rPt = rPoly[ b ]; 4520 sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - rPt.X(), aRefPoint.Y - rPt.Y() ); 4521 if ( nDist < nDistance ) 4522 { 4523 nRule = nIndex; 4524 nDistance = nDist; 4525 } 4526 nIndex++; 4527 } 4528 } 4529 if ( nDistance != 0xffffffff ) 4530 bRectangularConnection = false; 4531 } 4532 } 4533 } 4534 } 4535 if ( bRectangularConnection ) 4536 { 4537 ::com::sun::star::awt::Point aPoint( aXShape->getPosition() ); 4538 ::com::sun::star::awt::Size aSize( aXShape->getSize() ); 4539 4540 Rectangle aRect( Point( aPoint.X, aPoint.Y ), Size( aSize.Width, aSize.Height ) ); 4541 Point aCenter( aRect.Center() ); 4542 Polygon aPoly( 4 ); 4543 4544 aPoly[ 0 ] = Point( aCenter.X(), aRect.Top() ); 4545 aPoly[ 1 ] = Point( aRect.Left(), aCenter.Y() ); 4546 aPoly[ 2 ] = Point( aCenter.X(), aRect.Bottom() ); 4547 aPoly[ 3 ] = Point( aRect.Right(), aCenter.Y() ); 4548 4549 sal_Int32 nAngle = ( EscherPropertyValueHelper::GetPropertyValue( aAny, 4550 aPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) ) 4551 ? *((sal_Int32*)aAny.getValue() ) 4552 : 0; 4553 if ( nAngle ) 4554 aPoly.Rotate( aRect.TopLeft(), (sal_uInt16)( ( nAngle + 5 ) / 10 ) ); 4555 nRule = GetClosestPoint( aPoly, aRefPoint ); 4556 4557 if ( aType == "drawing.Ellipse" ) 4558 nRule <<= 1; // In PPT hat eine Ellipse 8 M?glichkeiten sich zu connecten 4559 } 4560 } 4561 return nRule; 4562 } 4563 4564 EscherSolverContainer::~EscherSolverContainer() 4565 { 4566 void* pP; 4567 4568 for( pP = maShapeList.First(); pP; pP = maShapeList.Next() ) 4569 delete (EscherShapeListEntry*)pP; 4570 for( pP = maConnectorList.First(); pP; pP = maConnectorList.Next() ) 4571 delete (EscherConnectorListEntry*)pP; 4572 } 4573 4574 void EscherSolverContainer::AddShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape, sal_uInt32 nId ) 4575 { 4576 maShapeList.Insert( new EscherShapeListEntry( rXShape, nId ), LIST_APPEND ); 4577 } 4578 4579 void EscherSolverContainer::AddConnector( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConnector, 4580 const ::com::sun::star::awt::Point& rPA, 4581 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConA, 4582 const ::com::sun::star::awt::Point& rPB, 4583 ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConB ) 4584 { 4585 maConnectorList.Insert( new EscherConnectorListEntry( rConnector, rPA, rConA, rPB, rConB ), LIST_APPEND ); 4586 } 4587 4588 sal_uInt32 EscherSolverContainer::GetShapeId( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) const 4589 { 4590 for ( EscherShapeListEntry* pPtr = (EscherShapeListEntry*)((List&)maShapeList).First(); 4591 pPtr; pPtr = (EscherShapeListEntry*)((List&)maShapeList).Next() ) 4592 { 4593 if ( rXShape == pPtr->aXShape ) 4594 return ( pPtr->n_EscherId ); 4595 } 4596 return 0; 4597 } 4598 4599 void EscherSolverContainer::WriteSolver( SvStream& rStrm ) 4600 { 4601 sal_uInt32 nCount = maConnectorList.Count(); 4602 if ( nCount ) 4603 { 4604 sal_uInt32 nRecHdPos, nCurrentPos, nSize; 4605 rStrm << (sal_uInt16)( ( nCount << 4 ) | 0xf ) // open an ESCHER_SolverContainer 4606 << (sal_uInt16)ESCHER_SolverContainer // 4607 << (sal_uInt32)0; // 4608 4609 nRecHdPos = rStrm.Tell() - 4; 4610 4611 EscherConnectorRule aConnectorRule; 4612 aConnectorRule.nRuleId = 2; 4613 for ( EscherConnectorListEntry* pPtr = (EscherConnectorListEntry*)maConnectorList.First(); 4614 pPtr; pPtr = (EscherConnectorListEntry*)maConnectorList.Next() ) 4615 { 4616 aConnectorRule.ncptiA = aConnectorRule.ncptiB = 0xffffffff; 4617 aConnectorRule.nShapeC = GetShapeId( pPtr->mXConnector ); 4618 aConnectorRule.nShapeA = GetShapeId( pPtr->mXConnectToA ); 4619 aConnectorRule.nShapeB = GetShapeId( pPtr->mXConnectToB ); 4620 4621 if ( aConnectorRule.nShapeC ) 4622 { 4623 if ( aConnectorRule.nShapeA ) 4624 aConnectorRule.ncptiA = pPtr->GetConnectorRule( sal_True ); 4625 if ( aConnectorRule.nShapeB ) 4626 aConnectorRule.ncptiB = pPtr->GetConnectorRule( sal_False ); 4627 } 4628 rStrm << (sal_uInt32)( ( ESCHER_ConnectorRule << 16 ) | 1 ) // atom hd 4629 << (sal_uInt32)24 // 4630 << aConnectorRule.nRuleId 4631 << aConnectorRule.nShapeA 4632 << aConnectorRule.nShapeB 4633 << aConnectorRule.nShapeC 4634 << aConnectorRule.ncptiA 4635 << aConnectorRule.ncptiB; 4636 4637 aConnectorRule.nRuleId += 2; 4638 } 4639 4640 nCurrentPos = rStrm.Tell(); // close the ESCHER_SolverContainer 4641 nSize = ( nCurrentPos - nRecHdPos ) - 4;// 4642 rStrm.Seek( nRecHdPos ); // 4643 rStrm << nSize; // 4644 rStrm.Seek( nCurrentPos ); // 4645 } 4646 } 4647 4648 // --------------------------------------------------------------------------------------------- 4649 4650 EscherExGlobal::EscherExGlobal( sal_uInt32 nGraphicProvFlags ) : 4651 EscherGraphicProvider( nGraphicProvFlags ), 4652 mpPicStrm( 0 ), 4653 mbHasDggCont( false ), 4654 mbPicStrmQueried( false ) 4655 { 4656 } 4657 4658 EscherExGlobal::~EscherExGlobal() 4659 { 4660 } 4661 4662 sal_uInt32 EscherExGlobal::GenerateDrawingId() 4663 { 4664 // new drawing starts a new cluster in the cluster table (cluster identifiers are one-based) 4665 sal_uInt32 nClusterId = static_cast< sal_uInt32 >( maClusterTable.size() + 1 ); 4666 // drawing identifiers are one-based 4667 sal_uInt32 nDrawingId = static_cast< sal_uInt32 >( maDrawingInfos.size() + 1 ); 4668 // prepare new entries in the tables 4669 maClusterTable.push_back( ClusterEntry( nDrawingId ) ); 4670 maDrawingInfos.push_back( DrawingInfo( nClusterId ) ); 4671 // return the new drawing identifier 4672 return nDrawingId; 4673 } 4674 4675 sal_uInt32 EscherExGlobal::GenerateShapeId( sal_uInt32 nDrawingId, bool bIsInSpgr ) 4676 { 4677 // drawing identifier is one-based 4678 size_t nDrawingIdx = nDrawingId - 1; 4679 OSL_ENSURE( nDrawingIdx < maDrawingInfos.size(), "EscherExGlobal::GenerateShapeId - invalid drawing ID" ); 4680 if( nDrawingIdx >= maDrawingInfos.size() ) 4681 return 0; 4682 DrawingInfo& rDrawingInfo = maDrawingInfos[ nDrawingIdx ]; 4683 4684 // cluster identifier in drawing info struct is one-based 4685 ClusterEntry* pClusterEntry = &maClusterTable[ rDrawingInfo.mnClusterId - 1 ]; 4686 4687 // check cluster overflow, create new cluster entry 4688 if( pClusterEntry->mnNextShapeId == DFF_DGG_CLUSTER_SIZE ) 4689 { 4690 // start a new cluster in the cluster table 4691 maClusterTable.push_back( ClusterEntry( nDrawingId ) ); 4692 pClusterEntry = &maClusterTable.back(); 4693 // new size of maClusterTable is equal to one-based identifier of the new cluster 4694 rDrawingInfo.mnClusterId = static_cast< sal_uInt32 >( maClusterTable.size() ); 4695 } 4696 4697 // build shape identifier from cluster identifier and next free cluster shape identifier 4698 rDrawingInfo.mnLastShapeId = static_cast< sal_uInt32 >( rDrawingInfo.mnClusterId * DFF_DGG_CLUSTER_SIZE + pClusterEntry->mnNextShapeId ); 4699 // update free shape identifier in cluster entry 4700 ++pClusterEntry->mnNextShapeId; 4701 /* Old code has counted the shapes only, if we are in a SPGRCONTAINER. Is 4702 this really intended? Maybe it's always true... */ 4703 if( bIsInSpgr ) 4704 ++rDrawingInfo.mnShapeCount; 4705 4706 // return the new shape identifier 4707 return rDrawingInfo.mnLastShapeId; 4708 } 4709 4710 sal_uInt32 EscherExGlobal::GetDrawingShapeCount( sal_uInt32 nDrawingId ) const 4711 { 4712 size_t nDrawingIdx = nDrawingId - 1; 4713 OSL_ENSURE( nDrawingIdx < maDrawingInfos.size(), "EscherExGlobal::GetDrawingShapeCount - invalid drawing ID" ); 4714 return (nDrawingIdx < maDrawingInfos.size()) ? maDrawingInfos[ nDrawingIdx ].mnShapeCount : 0; 4715 } 4716 4717 sal_uInt32 EscherExGlobal::GetLastShapeId( sal_uInt32 nDrawingId ) const 4718 { 4719 size_t nDrawingIdx = nDrawingId - 1; 4720 OSL_ENSURE( nDrawingIdx < maDrawingInfos.size(), "EscherExGlobal::GetLastShapeId - invalid drawing ID" ); 4721 return (nDrawingIdx < maDrawingInfos.size()) ? maDrawingInfos[ nDrawingIdx ].mnLastShapeId : 0; 4722 } 4723 4724 sal_uInt32 EscherExGlobal::GetDggAtomSize() const 4725 { 4726 // 8 bytes header, 16 bytes fixed DGG data, 8 bytes for each cluster 4727 return static_cast< sal_uInt32 >( 24 + 8 * maClusterTable.size() ); 4728 } 4729 4730 void EscherExGlobal::WriteDggAtom( SvStream& rStrm ) const 4731 { 4732 sal_uInt32 nDggSize = GetDggAtomSize(); 4733 4734 // write the DGG record header (do not include the 8 bytes of the header in the data size) 4735 rStrm << static_cast< sal_uInt32 >( ESCHER_Dgg << 16 ) << static_cast< sal_uInt32 >( nDggSize - 8 ); 4736 4737 // claculate and write the fixed DGG data 4738 sal_uInt32 nShapeCount = 0; 4739 sal_uInt32 nLastShapeId = 0; 4740 for( DrawingInfoVector::const_iterator aIt = maDrawingInfos.begin(), aEnd = maDrawingInfos.end(); aIt != aEnd; ++aIt ) 4741 { 4742 nShapeCount += aIt->mnShapeCount; 4743 nLastShapeId = ::std::max( nLastShapeId, aIt->mnLastShapeId ); 4744 } 4745 // the non-existing cluster with index #0 is counted too 4746 sal_uInt32 nClusterCount = static_cast< sal_uInt32 >( maClusterTable.size() + 1 ); 4747 sal_uInt32 nDrawingCount = static_cast< sal_uInt32 >( maDrawingInfos.size() ); 4748 rStrm << nLastShapeId << nClusterCount << nShapeCount << nDrawingCount; 4749 4750 // write the cluster table 4751 for( ClusterTable::const_iterator aIt = maClusterTable.begin(), aEnd = maClusterTable.end(); aIt != aEnd; ++aIt ) 4752 rStrm << aIt->mnDrawingId << aIt->mnNextShapeId; 4753 } 4754 4755 SvStream* EscherExGlobal::QueryPictureStream() 4756 { 4757 if( !mbPicStrmQueried ) 4758 { 4759 mpPicStrm = ImplQueryPictureStream(); 4760 mbPicStrmQueried = true; 4761 } 4762 return mpPicStrm; 4763 } 4764 4765 SvStream* EscherExGlobal::ImplQueryPictureStream() 4766 { 4767 return 0; 4768 } 4769 4770 // --------------------------------------------------------------------------------------------- 4771 // --------------------------------------------------------------------------------------------- 4772 // --------------------------------------------------------------------------------------------- 4773 4774 EscherEx::EscherEx( const EscherExGlobalRef& rxGlobal, SvStream& rOutStrm ) : 4775 mxGlobal ( rxGlobal ), 4776 mpOutStrm ( &rOutStrm ), 4777 4778 mnGroupLevel ( 0 ), 4779 mnHellLayerId ( USHRT_MAX ), 4780 4781 mbEscherSpgr ( sal_False ), 4782 mbEscherDg ( sal_False ) 4783 { 4784 mnStrmStartOfs = mpOutStrm->Tell(); 4785 mpImplEscherExSdr.reset( new ImplEscherExSdr( *this ) ); 4786 } 4787 4788 EscherEx::~EscherEx() 4789 { 4790 } 4791 4792 // --------------------------------------------------------------------------------------------- 4793 4794 void EscherEx::Flush( SvStream* pPicStreamMergeBSE /* = NULL */ ) 4795 { 4796 if ( mxGlobal->HasDggContainer() ) 4797 { 4798 // store the current stream position at ESCHER_Persist_CurrentPosition key 4799 PtReplaceOrInsert( ESCHER_Persist_CurrentPosition, mpOutStrm->Tell() ); 4800 if ( DoSeek( ESCHER_Persist_Dgg ) ) 4801 { 4802 /* The DGG record is still not written. ESCHER_Persist_Dgg seeks 4803 to the place where the complete record has to be inserted. */ 4804 InsertAtCurrentPos( mxGlobal->GetDggAtomSize(), false ); 4805 mxGlobal->WriteDggAtom( *mpOutStrm ); 4806 4807 if ( mxGlobal->HasGraphics() ) 4808 { 4809 /* Calculate the total size of the BSTORECONTAINER including 4810 all BSE records containing the picture data contained in 4811 the passed in pPicStreamMergeBSE. */ 4812 sal_uInt32 nBSCSize = mxGlobal->GetBlibStoreContainerSize( pPicStreamMergeBSE ); 4813 if ( nBSCSize > 0 ) 4814 { 4815 InsertAtCurrentPos( nBSCSize, false ); 4816 mxGlobal->WriteBlibStoreContainer( *mpOutStrm, pPicStreamMergeBSE ); 4817 } 4818 } 4819 4820 /* Forget the stream position stored for the DGG which is invalid 4821 after the call to InsertAtCurrentPos() anyway. */ 4822 PtDelete( ESCHER_Persist_Dgg ); 4823 } 4824 // seek to initial position (may be different due to inserted DGG and BLIPs) 4825 mpOutStrm->Seek( PtGetOffsetByID( ESCHER_Persist_CurrentPosition ) ); 4826 } 4827 } 4828 4829 // --------------------------------------------------------------------------------------------- 4830 4831 void EscherEx::InsertAtCurrentPos( sal_uInt32 nBytes, bool bExpandEndOfAtom ) 4832 { 4833 sal_uInt32 nSize, nType, nSource, nBufSize, nToCopy, nCurPos = mpOutStrm->Tell(); 4834 sal_uInt8* pBuf; 4835 4836 // Persist table anpassen 4837 for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() ) 4838 { 4839 sal_uInt32 nOfs = ((EscherPersistEntry*)pPtr)->mnOffset; 4840 if ( nOfs >= nCurPos ) 4841 ((EscherPersistEntry*)pPtr)->mnOffset += nBytes; 4842 } 4843 4844 // container und atom sizes anpassen 4845 mpOutStrm->Seek( mnStrmStartOfs ); 4846 while ( mpOutStrm->Tell() < nCurPos ) 4847 { 4848 *mpOutStrm >> nType >> nSize; 4849 sal_uInt32 nEndOfRecord = mpOutStrm->Tell() + nSize; 4850 bool bContainer = (nType & 0x0F) == 0x0F; 4851 /* Expand the record, if the insertion position is inside, or if the 4852 position is at the end of a container (expands always), or at the 4853 end of an atom and bExpandEndOfAtom is set. */ 4854 if ( (nCurPos < nEndOfRecord) || ((nCurPos == nEndOfRecord) && (bContainer || bExpandEndOfAtom)) ) 4855 { 4856 mpOutStrm->SeekRel( -4 ); 4857 *mpOutStrm << (sal_uInt32)( nSize + nBytes ); 4858 if ( !bContainer ) 4859 mpOutStrm->SeekRel( nSize ); 4860 } 4861 else 4862 mpOutStrm->SeekRel( nSize ); 4863 } 4864 std::vector< sal_uInt32 >::iterator aIter( mOffsets.begin() ); 4865 std::vector< sal_uInt32 >::iterator aEnd( mOffsets.end() ); 4866 while( aIter != aEnd ) 4867 { 4868 if ( *aIter > nCurPos ) 4869 *aIter += nBytes; 4870 aIter++; 4871 } 4872 mpOutStrm->Seek( STREAM_SEEK_TO_END ); 4873 nSource = mpOutStrm->Tell(); 4874 nToCopy = nSource - nCurPos; // Stream um nBytes vergroessern 4875 pBuf = new sal_uInt8[ 0x40000 ]; // 256KB Buffer 4876 while ( nToCopy ) 4877 { 4878 nBufSize = ( nToCopy >= 0x40000 ) ? 0x40000 : nToCopy; 4879 nToCopy -= nBufSize; 4880 nSource -= nBufSize; 4881 mpOutStrm->Seek( nSource ); 4882 mpOutStrm->Read( pBuf, nBufSize ); 4883 mpOutStrm->Seek( nSource + nBytes ); 4884 mpOutStrm->Write( pBuf, nBufSize ); 4885 } 4886 delete[] pBuf; 4887 mpOutStrm->Seek( nCurPos ); 4888 } 4889 4890 // --------------------------------------------------------------------------------------------- 4891 4892 sal_Bool EscherEx::SeekBehindRecHeader( sal_uInt16 nRecType ) 4893 { 4894 sal_uInt32 nOldPos, nStreamEnd, nType, nSize; 4895 4896 nOldPos = mpOutStrm->Tell(); 4897 nStreamEnd = mpOutStrm->Seek( STREAM_SEEK_TO_END ); 4898 mpOutStrm->Seek( nOldPos ); 4899 while ( mpOutStrm->Tell() < nStreamEnd ) 4900 { 4901 *mpOutStrm >> nType >> nSize; 4902 if ( ( nType >> 16 ) == nRecType ) 4903 return sal_True; 4904 if ( ( nType & 0xf ) != 0xf ) 4905 mpOutStrm->SeekRel( nSize ); 4906 } 4907 mpOutStrm->Seek( nOldPos ); 4908 return sal_False; 4909 } 4910 4911 // --------------------------------------------------------------------------------------------- 4912 4913 void EscherEx::InsertPersistOffset( sal_uInt32 nKey, sal_uInt32 nOffset ) 4914 { 4915 PtInsert( ESCHER_Persist_PrivateEntry | nKey, nOffset ); 4916 } 4917 4918 void EscherEx::ReplacePersistOffset( sal_uInt32 nKey, sal_uInt32 nOffset ) 4919 { 4920 PtReplace( ESCHER_Persist_PrivateEntry | nKey, nOffset ); 4921 } 4922 4923 sal_uInt32 EscherEx::GetPersistOffset( sal_uInt32 nKey ) 4924 { 4925 return PtGetOffsetByID( ESCHER_Persist_PrivateEntry | nKey ); 4926 } 4927 4928 // --------------------------------------------------------------------------------------------- 4929 4930 sal_Bool EscherEx::DoSeek( sal_uInt32 nKey ) 4931 { 4932 sal_uInt32 nPos = PtGetOffsetByID( nKey ); 4933 if ( nPos ) 4934 mpOutStrm->Seek( nPos ); 4935 else 4936 { 4937 if (! PtIsID( nKey ) ) 4938 return sal_False; 4939 mpOutStrm->Seek( 0 ); 4940 } 4941 return sal_True; 4942 } 4943 4944 // --------------------------------------------------------------------------------------------- 4945 4946 sal_Bool EscherEx::SeekToPersistOffset( sal_uInt32 nKey ) 4947 { 4948 return DoSeek( ESCHER_Persist_PrivateEntry | nKey ); 4949 } 4950 4951 // --------------------------------------------------------------------------------------------- 4952 4953 sal_Bool EscherEx::InsertAtPersistOffset( sal_uInt32 nKey, sal_uInt32 nValue ) 4954 { 4955 sal_uInt32 nOldPos = mpOutStrm->Tell(); 4956 sal_Bool bRetValue = SeekToPersistOffset( nKey ); 4957 if ( bRetValue ) 4958 { 4959 *mpOutStrm << nValue; 4960 mpOutStrm->Seek( nOldPos ); 4961 } 4962 return bRetValue; 4963 } 4964 4965 // --------------------------------------------------------------------------------------------- 4966 4967 void EscherEx::OpenContainer( sal_uInt16 nEscherContainer, int nRecInstance ) 4968 { 4969 *mpOutStrm << (sal_uInt16)( ( nRecInstance << 4 ) | 0xf ) << nEscherContainer << (sal_uInt32)0; 4970 mOffsets.push_back( mpOutStrm->Tell() - 4 ); 4971 mRecTypes.push_back( nEscherContainer ); 4972 switch( nEscherContainer ) 4973 { 4974 case ESCHER_DggContainer : 4975 { 4976 mxGlobal->SetDggContainer(); 4977 mnCurrentDg = 0; 4978 /* Remember the current position as start position of the DGG 4979 record and BSTORECONTAINER, but do not write them actually. 4980 This will be done later in Flush() when the number of drawings, 4981 the size and contents of the FIDCL cluster table, and the size 4982 of the BLIP container are known. */ 4983 PtReplaceOrInsert( ESCHER_Persist_Dgg, mpOutStrm->Tell() ); 4984 } 4985 break; 4986 4987 case ESCHER_DgContainer : 4988 { 4989 if ( mxGlobal->HasDggContainer() ) 4990 { 4991 if ( !mbEscherDg ) 4992 { 4993 mbEscherDg = sal_True; 4994 mnCurrentDg = mxGlobal->GenerateDrawingId(); 4995 AddAtom( 8, ESCHER_Dg, 0, mnCurrentDg ); 4996 PtReplaceOrInsert( ESCHER_Persist_Dg | mnCurrentDg, mpOutStrm->Tell() ); 4997 *mpOutStrm << (sal_uInt32)0 // The number of shapes in this drawing 4998 << (sal_uInt32)0; // The last MSOSPID given to an SP in this DG 4999 } 5000 } 5001 } 5002 break; 5003 5004 case ESCHER_SpgrContainer : 5005 { 5006 if ( mbEscherDg ) 5007 { 5008 mbEscherSpgr = sal_True; 5009 } 5010 } 5011 break; 5012 5013 case ESCHER_SpContainer : 5014 { 5015 } 5016 break; 5017 5018 default: 5019 break; 5020 } 5021 } 5022 5023 // --------------------------------------------------------------------------------------------- 5024 5025 void EscherEx::CloseContainer() 5026 { 5027 sal_uInt32 nSize, nPos = mpOutStrm->Tell(); 5028 nSize = ( nPos - mOffsets.back() ) - 4; 5029 mpOutStrm->Seek( mOffsets.back() ); 5030 *mpOutStrm << nSize; 5031 5032 switch( mRecTypes.back() ) 5033 { 5034 case ESCHER_DgContainer : 5035 { 5036 if ( mbEscherDg ) 5037 { 5038 mbEscherDg = sal_False; 5039 if ( DoSeek( ESCHER_Persist_Dg | mnCurrentDg ) ) 5040 *mpOutStrm << mxGlobal->GetDrawingShapeCount( mnCurrentDg ) << mxGlobal->GetLastShapeId( mnCurrentDg ); 5041 } 5042 } 5043 break; 5044 5045 case ESCHER_SpgrContainer : 5046 { 5047 if ( mbEscherSpgr ) 5048 { 5049 mbEscherSpgr = sal_False; 5050 5051 } 5052 } 5053 break; 5054 5055 default: 5056 break; 5057 } 5058 mOffsets.pop_back(); 5059 mRecTypes.pop_back(); 5060 mpOutStrm->Seek( nPos ); 5061 } 5062 5063 // --------------------------------------------------------------------------------------------- 5064 5065 void EscherEx::BeginAtom() 5066 { 5067 mnCountOfs = mpOutStrm->Tell(); 5068 *mpOutStrm << (sal_uInt32)0 << (sal_uInt32)0; // record header wird spaeter geschrieben 5069 } 5070 5071 // --------------------------------------------------------------------------------------------- 5072 5073 void EscherEx::EndAtom( sal_uInt16 nRecType, int nRecVersion, int nRecInstance ) 5074 { 5075 sal_uInt32 nOldPos = mpOutStrm->Tell(); 5076 mpOutStrm->Seek( mnCountOfs ); 5077 sal_uInt32 nSize = nOldPos - mnCountOfs; 5078 *mpOutStrm << (sal_uInt16)( ( nRecInstance << 4 ) | ( nRecVersion & 0xf ) ) << nRecType << (sal_uInt32)( nSize - 8 ); 5079 mpOutStrm->Seek( nOldPos ); 5080 } 5081 5082 // --------------------------------------------------------------------------------------------- 5083 5084 void EscherEx::AddAtom( sal_uInt32 nAtomSize, sal_uInt16 nRecType, int nRecVersion, int nRecInstance ) 5085 { 5086 *mpOutStrm << (sal_uInt16)( ( nRecInstance << 4 ) | ( nRecVersion & 0xf ) ) << nRecType << nAtomSize; 5087 } 5088 5089 // --------------------------------------------------------------------------------------------- 5090 5091 void EscherEx::AddChildAnchor( const Rectangle& rRect ) 5092 { 5093 AddAtom( 16, ESCHER_ChildAnchor ); 5094 *mpOutStrm << (sal_Int32)rRect.Left() 5095 << (sal_Int32)rRect.Top() 5096 << (sal_Int32)rRect.Right() 5097 << (sal_Int32)rRect.Bottom(); 5098 } 5099 5100 // --------------------------------------------------------------------------------------------- 5101 5102 void EscherEx::AddClientAnchor( const Rectangle& rRect ) 5103 { 5104 AddAtom( 8, ESCHER_ClientAnchor ); 5105 *mpOutStrm << (sal_Int16)rRect.Top() 5106 << (sal_Int16)rRect.Left() 5107 << (sal_Int16)( rRect.GetWidth() + rRect.Left() ) 5108 << (sal_Int16)( rRect.GetHeight() + rRect.Top() ); 5109 } 5110 5111 // --------------------------------------------------------------------------------------------- 5112 5113 EscherExHostAppData* EscherEx::EnterAdditionalTextGroup() 5114 { 5115 return NULL; 5116 } 5117 5118 // --------------------------------------------------------------------------------------------- 5119 5120 sal_uInt32 EscherEx::EnterGroup( const String& rShapeName, const Rectangle* pBoundRect ) 5121 { 5122 Rectangle aRect; 5123 if( pBoundRect ) 5124 aRect = *pBoundRect; 5125 5126 OpenContainer( ESCHER_SpgrContainer ); 5127 OpenContainer( ESCHER_SpContainer ); 5128 AddAtom( 16, ESCHER_Spgr, 1 ); 5129 PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap | mnGroupLevel, 5130 mpOutStrm->Tell() ); 5131 *mpOutStrm << (sal_Int32)aRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden 5132 << (sal_Int32)aRect.Top() 5133 << (sal_Int32)aRect.Right() 5134 << (sal_Int32)aRect.Bottom(); 5135 5136 sal_uInt32 nShapeId = GenerateShapeId(); 5137 if ( !mnGroupLevel ) 5138 AddShape( ESCHER_ShpInst_Min, 5, nShapeId ); // Flags: Group | Patriarch 5139 else 5140 { 5141 AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId ); // Flags: Group | HaveAnchor 5142 EscherPropertyContainer aPropOpt; 5143 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x00040004 ); 5144 aPropOpt.AddOpt( ESCHER_Prop_dxWrapDistLeft, 0 ); 5145 aPropOpt.AddOpt( ESCHER_Prop_dxWrapDistRight, 0 ); 5146 5147 // #i51348# shape name 5148 if( rShapeName.Len() > 0 ) 5149 aPropOpt.AddOpt( ESCHER_Prop_wzName, rShapeName ); 5150 5151 Commit( aPropOpt, aRect ); 5152 if ( mnGroupLevel > 1 ) 5153 AddChildAnchor( aRect ); 5154 5155 EscherExHostAppData* pAppData = mpImplEscherExSdr->ImplGetHostData(); 5156 if( pAppData ) 5157 { 5158 if ( mnGroupLevel <= 1 ) 5159 pAppData->WriteClientAnchor( *this, aRect ); 5160 pAppData->WriteClientData( *this ); 5161 } 5162 } 5163 CloseContainer(); // ESCHER_SpContainer 5164 mnGroupLevel++; 5165 return nShapeId; 5166 } 5167 5168 sal_uInt32 EscherEx::EnterGroup( const Rectangle* pBoundRect ) 5169 { 5170 return EnterGroup( String::EmptyString(), pBoundRect ); 5171 } 5172 5173 // --------------------------------------------------------------------------------------------- 5174 5175 sal_Bool EscherEx::SetGroupSnapRect( sal_uInt32 nGroupLevel, const Rectangle& rRect ) 5176 { 5177 sal_Bool bRetValue = sal_False; 5178 if ( nGroupLevel ) 5179 { 5180 sal_uInt32 nCurrentPos = mpOutStrm->Tell(); 5181 if ( DoSeek( ESCHER_Persist_Grouping_Snap | ( nGroupLevel - 1 ) ) ) 5182 { 5183 *mpOutStrm << (sal_Int32)rRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden 5184 << (sal_Int32)rRect.Top() 5185 << (sal_Int32)rRect.Right() 5186 << (sal_Int32)rRect.Bottom(); 5187 mpOutStrm->Seek( nCurrentPos ); 5188 } 5189 } 5190 return bRetValue; 5191 } 5192 5193 // --------------------------------------------------------------------------------------------- 5194 5195 sal_Bool EscherEx::SetGroupLogicRect( sal_uInt32 nGroupLevel, const Rectangle& rRect ) 5196 { 5197 sal_Bool bRetValue = sal_False; 5198 if ( nGroupLevel ) 5199 { 5200 sal_uInt32 nCurrentPos = mpOutStrm->Tell(); 5201 if ( DoSeek( ESCHER_Persist_Grouping_Logic | ( nGroupLevel - 1 ) ) ) 5202 { 5203 *mpOutStrm << (sal_Int16)rRect.Top() << (sal_Int16)rRect.Left() << (sal_Int16)rRect.Right() << (sal_Int16)rRect.Bottom(); 5204 mpOutStrm->Seek( nCurrentPos ); 5205 } 5206 } 5207 return bRetValue; 5208 } 5209 5210 // --------------------------------------------------------------------------------------------- 5211 5212 void EscherEx::LeaveGroup() 5213 { 5214 --mnGroupLevel; 5215 PtDelete( ESCHER_Persist_Grouping_Snap | mnGroupLevel ); 5216 PtDelete( ESCHER_Persist_Grouping_Logic | mnGroupLevel ); 5217 CloseContainer(); 5218 } 5219 5220 // --------------------------------------------------------------------------------------------- 5221 5222 void EscherEx::AddShape( sal_uInt32 nShpInstance, sal_uInt32 nFlags, sal_uInt32 nShapeID ) 5223 { 5224 AddAtom( 8, ESCHER_Sp, 2, nShpInstance ); 5225 5226 if ( !nShapeID ) 5227 nShapeID = GenerateShapeId(); 5228 5229 if ( nFlags ^ 1 ) // is this a group shape ? 5230 { // if not 5231 if ( mnGroupLevel > 1 ) 5232 nFlags |= 2; // this not a topmost shape 5233 } 5234 *mpOutStrm << nShapeID << nFlags; 5235 } 5236 5237 // --------------------------------------------------------------------------------------------- 5238 5239 void EscherEx::Commit( EscherPropertyContainer& rProps, const Rectangle& ) 5240 { 5241 rProps.Commit( GetStream() ); 5242 } 5243 5244 // --------------------------------------------------------------------------------------------- 5245 5246 sal_uInt32 EscherEx::GetColor( const sal_uInt32 nSOColor, sal_Bool bSwap ) 5247 { 5248 if ( bSwap ) 5249 { 5250 sal_uInt32 nColor = nSOColor & 0xff00; // GRUEN 5251 nColor |= (sal_uInt8)( nSOColor ) << 16; // ROT 5252 nColor |= (sal_uInt8)( nSOColor >> 16 ); // BLAU 5253 return nColor; 5254 } 5255 else 5256 return nSOColor & 0xffffff; 5257 } 5258 5259 // --------------------------------------------------------------------------------------------- 5260 5261 sal_uInt32 EscherEx::GetColor( const Color& rSOColor, sal_Bool bSwap ) 5262 { 5263 sal_uInt32 nColor = ( rSOColor.GetRed() << 16 ); 5264 nColor |= ( rSOColor.GetGreen() << 8 ); 5265 nColor |= rSOColor.GetBlue(); 5266 5267 if ( !bSwap ) 5268 nColor = GetColor( nColor, sal_True ); 5269 5270 return nColor; 5271 } 5272 5273 // --------------------------------------------------------------------------------------------- 5274 5275