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