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