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