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