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 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ 27 #include <com/sun/star/embed/Aspects.hpp> 28 29 #include <math.h> 30 #include <limits.h> 31 #include <vector> 32 #include <osl/endian.h> 33 #include <tools/solar.h> // UINTXX 34 #include <rtl/math.hxx> 35 36 #include <sot/clsids.hxx> 37 #include <toolkit/helper/vclunohelper.hxx> 38 #include <unotools/streamwrap.hxx> 39 #include <comphelper/processfactory.hxx> 40 #include <comphelper/seqstream.hxx> 41 #include <comphelper/storagehelper.hxx> 42 #include <sot/exchange.hxx> 43 #include <sot/storinfo.hxx> 44 #include <vcl/cvtgrf.hxx> 45 #include "viscache.hxx" 46 47 // SvxItem-Mapping. Wird benoetigt um die SvxItem-Header erfolgreich zu includen 48 #include <editeng/eeitem.hxx> 49 #include <editeng/editdata.hxx> 50 #include <svl/urihelper.hxx> 51 #include <tools/stream.hxx> 52 #include <tools/debug.hxx> 53 #include <tools/zcodec.hxx> 54 #include <unotools/ucbstreamhelper.hxx> 55 #include <unotools/localfilehelper.hxx> 56 #include <filter/msfilter/escherex.hxx> 57 #include <basegfx/range/b2drange.hxx> 58 #include <com/sun/star/container/XIdentifierContainer.hpp> 59 #include <com/sun/star/drawing/XGluePointsSupplier.hpp> 60 #include <com/sun/star/drawing/Position3D.hpp> 61 #include <com/sun/star/drawing/Direction3D.hpp> 62 #include <com/sun/star/drawing/GluePoint2.hpp> 63 #include <com/sun/star/drawing/XShapes.hpp> 64 #include <editeng/charscaleitem.hxx> 65 #include <editeng/kernitem.hxx> 66 #include <svtools/filter.hxx> 67 #include <tools/string.hxx> 68 #include <tools/urlobj.hxx> 69 #include <vcl/virdev.hxx> 70 #include <vcl/bmpacc.hxx> 71 #include <sot/storage.hxx> 72 #include <sfx2/docfac.hxx> 73 #include <sfx2/docfilt.hxx> 74 #include <sfx2/docfile.hxx> 75 #include <sfx2/fcontnr.hxx> 76 #include <sfx2/module.hxx> 77 #include <svx/sdgcpitm.hxx> 78 #include <svx/sdgmoitm.hxx> 79 #include <editeng/tstpitem.hxx> 80 #include <svx/fmmodel.hxx> 81 #include <svx/svdmodel.hxx> 82 #include <svx/svdobj.hxx> 83 #include <svx/svdpage.hxx> 84 #include <svx/svdogrp.hxx> 85 #include <svx/svdograf.hxx> 86 #include <svx/svdotext.hxx> 87 #include <svx/svdorect.hxx> 88 #include <svx/svdocapt.hxx> 89 #include <svx/svdoedge.hxx> 90 #include <svx/svdocirc.hxx> 91 #include <svx/svdoutl.hxx> 92 #include <svx/svdoole2.hxx> 93 #include <svx/svdopath.hxx> 94 #include <editeng/frmdir.hxx> 95 #include <editeng/frmdiritem.hxx> 96 #include <svx/svdtrans.hxx> 97 #include <svx/sxenditm.hxx> 98 #include <svx/sdgluitm.hxx> 99 #include <editeng/fhgtitem.hxx> 100 #include <editeng/wghtitem.hxx> 101 #include <editeng/postitem.hxx> 102 #include <editeng/udlnitem.hxx> 103 #include <editeng/crsditem.hxx> 104 #include <editeng/shdditem.hxx> 105 #include <editeng/fontitem.hxx> 106 #include <editeng/colritem.hxx> 107 #include <svx/sxekitm.hxx> 108 #include <editeng/bulitem.hxx> 109 #include <svx/polysc3d.hxx> 110 #include <svx/extrud3d.hxx> 111 #include "svx/svditer.hxx" 112 #include <svx/xpoly.hxx> 113 #include "svx/xattr.hxx" 114 #include <filter/msfilter/msdffimp.hxx> // extern sichtbare Header-Datei 115 #include <editeng/outliner.hxx> 116 #include <editeng/outlobj.hxx> 117 #include <editeng/editobj.hxx> 118 #include <editeng/editeng.hxx> 119 #include "svx/gallery.hxx" 120 #include <com/sun/star/drawing/ShadeMode.hpp> 121 #include <svl/itempool.hxx> 122 #include <vcl/svapp.hxx> 123 #include <svx/svx3ditems.hxx> 124 #include <svx/svdoashp.hxx> 125 #include <svx/sdasaitm.hxx> 126 #include <ucbhelper/content.hxx> 127 #include <ucbhelper/contentbroker.hxx> 128 #include <vos/xception.hxx> 129 using namespace vos; 130 #include "svx/EnhancedCustomShapeTypeNames.hxx" 131 #include "svx/EnhancedCustomShapeGeometry.hxx" 132 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp> 133 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp> 134 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp> 135 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp> 136 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp> 137 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp> 138 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> 139 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp> 140 #include <com/sun/star/beans/PropertyValues.hpp> 141 #include <com/sun/star/drawing/ProjectionMode.hpp> 142 #include "svx/EnhancedCustomShape2d.hxx" 143 144 using namespace ::com::sun::star ; 145 using namespace ::com::sun::star::drawing; 146 using namespace uno ; 147 using namespace beans ; 148 using namespace drawing ; 149 using namespace container ; 150 151 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue() 152 153 // static counter for OLE-Objects 154 static sal_uInt32 nMSOleObjCntr = 0; 155 #define MSO_OLE_Obj "MSO_OLE_Obj" 156 157 /************************************************************************/ 158 void Impl_OlePres::Write( SvStream & rStm ) 159 { 160 WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE ); 161 rStm << (sal_Int32)(nJobLen +4); // immer leeres TargetDevice 162 if( nJobLen ) 163 rStm.Write( pJob, nJobLen ); 164 rStm << (sal_uInt32)nAspect; 165 rStm << (sal_Int32)-1; //L-Index immer -1 166 rStm << (sal_Int32)nAdvFlags; 167 rStm << (sal_Int32)0; //Compression 168 rStm << (sal_Int32)aSize.Width(); 169 rStm << (sal_Int32)aSize.Height(); 170 sal_uLong nPos = rStm.Tell(); 171 rStm << (sal_Int32)0; 172 173 if( GetFormat() == FORMAT_GDIMETAFILE && pMtf ) 174 { 175 // Immer auf 1/100 mm, bis Mtf-Loesung gefunden 176 // Annahme (keine Skalierung, keine Org-Verschiebung) 177 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ), 178 "X-Skalierung im Mtf" ); 179 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ), 180 "Y-Skalierung im Mtf" ); 181 DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(), 182 "Origin-Verschiebung im Mtf" ); 183 MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit(); 184 if( MAP_100TH_MM != nMU ) 185 { 186 Size aPrefS( pMtf->GetPrefSize() ); 187 Size aS( aPrefS ); 188 aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM ); 189 190 pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ), 191 Fraction( aS.Height(), aPrefS.Height() ) ); 192 pMtf->SetPrefMapMode( MAP_100TH_MM ); 193 pMtf->SetPrefSize( aS ); 194 } 195 WriteWindowMetafileBits( rStm, *pMtf ); 196 } 197 else 198 { 199 DBG_ERROR( "unknown format" ); 200 } 201 sal_uLong nEndPos = rStm.Tell(); 202 rStm.Seek( nPos ); 203 rStm << (sal_uInt32)(nEndPos - nPos - 4); 204 rStm.Seek( nEndPos ); 205 } 206 207 //--------------------------------------------------------------------------- 208 // Hilfs Klassen aus MSDFFDEF.HXX 209 //--------------------------------------------------------------------------- 210 211 // Masse fuer dashed lines 212 #define LLEN_MIDDLE (450) 213 #define LLEN_SPACE_MIDDLE (360) 214 #define LLEN_LONG (LLEN_MIDDLE * 2) 215 #define LLEN_SPACE_LONG (LLEN_SPACE_MIDDLE + 20) 216 #define LLEN_POINT (LLEN_MIDDLE / 4) 217 #define LLEN_SPACE_POINT (LLEN_SPACE_MIDDLE / 4) 218 219 DffPropertyReader::DffPropertyReader( const SvxMSDffManager& rMan ) : 220 rManager( rMan ), 221 pDefaultPropSet( NULL ) 222 { 223 InitializePropSet( DFF_msofbtOPT ); 224 } 225 226 void DffPropertyReader::SetDefaultPropSet( SvStream& rStCtrl, sal_uInt32 nOffsDgg ) const 227 { 228 delete pDefaultPropSet; 229 sal_uInt32 nMerk = rStCtrl.Tell(); 230 rStCtrl.Seek( nOffsDgg ); 231 DffRecordHeader aRecHd; 232 rStCtrl >> aRecHd; 233 if ( aRecHd.nRecType == DFF_msofbtDggContainer ) 234 { 235 if ( rManager.SeekToRec( rStCtrl, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) ) 236 { 237 ( (DffPropertyReader*) this )->pDefaultPropSet = new DffPropSet; 238 rStCtrl >> *pDefaultPropSet; 239 } 240 } 241 rStCtrl.Seek( nMerk ); 242 } 243 244 #ifdef DBG_CUSTOMSHAPE 245 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData, sal_uInt32 nShapeId ) const 246 #else 247 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData ) const 248 #endif 249 { 250 sal_uLong nFilePos = rIn.Tell(); 251 rIn >> (DffPropertyReader&)*this; 252 253 if ( IsProperty( DFF_Prop_hspMaster ) ) 254 { 255 if ( rManager.SeekToShape( rIn, pClientData, GetPropertyValue( DFF_Prop_hspMaster ) ) ) 256 { 257 DffRecordHeader aRecHd; 258 rIn >> aRecHd; 259 if ( rManager.SeekToRec( rIn, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) ) 260 { 261 rIn |= (DffPropertyReader&)*this; 262 } 263 } 264 } 265 ( (DffPropertyReader*) this )->mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) ); 266 267 #ifdef DBG_CUSTOMSHAPE 268 269 String aURLStr; 270 271 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_STRINGPARAM( "d:\\ashape.dbg" ) ), aURLStr ) ) 272 { 273 SvStream* pOut = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE ); 274 275 if( pOut ) 276 { 277 pOut->Seek( STREAM_SEEK_TO_END ); 278 279 if ( IsProperty( DFF_Prop_adjustValue ) || IsProperty( DFF_Prop_pVertices ) ) 280 { 281 pOut->WriteLine( "" ); 282 ByteString aString( "ShapeId: " ); 283 aString.Append( ByteString::CreateFromInt32( nShapeId ) ); 284 pOut->WriteLine( aString ); 285 } 286 for ( sal_uInt32 i = DFF_Prop_adjustValue; i <= DFF_Prop_adjust10Value; i++ ) 287 { 288 if ( IsProperty( i ) ) 289 { 290 ByteString aString( "Prop_adjustValue" ); 291 aString.Append( ByteString::CreateFromInt32( ( i - DFF_Prop_adjustValue ) + 1 ) ); 292 aString.Append( ":" ); 293 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) ); 294 pOut->WriteLine( aString ); 295 } 296 } 297 sal_Int32 i; 298 for ( i = 320; i < 383; i++ ) 299 { 300 if ( ( i >= DFF_Prop_adjustValue ) && ( i <= DFF_Prop_adjust10Value ) ) 301 continue; 302 if ( IsProperty( i ) ) 303 { 304 if ( SeekToContent( i, rIn ) ) 305 { 306 sal_Int32 nLen = (sal_Int32)GetPropertyValue( i ); 307 if ( nLen ) 308 { 309 pOut->WriteLine( "" ); 310 ByteString aDesc( "Property:" ); 311 aDesc.Append( ByteString::CreateFromInt32( i ) ); 312 aDesc.Append( ByteString( " Size:" ) ); 313 aDesc.Append( ByteString::CreateFromInt32( nLen ) ); 314 pOut->WriteLine( aDesc ); 315 sal_Int16 nNumElem, nNumElemMem, nNumSize; 316 rIn >> nNumElem >> nNumElemMem >> nNumSize; 317 aDesc = ByteString( "Entries: " ); 318 aDesc.Append( ByteString::CreateFromInt32( nNumElem ) ); 319 aDesc.Append( ByteString( " Size:" ) ); 320 aDesc.Append( ByteString::CreateFromInt32( nNumSize ) ); 321 pOut->WriteLine( aDesc ); 322 if ( nNumSize < 0 ) 323 nNumSize = ( ( -nNumSize ) >> 2 ); 324 if ( !nNumSize ) 325 nNumSize = 16; 326 nLen -= 6; 327 while ( nLen > 0 ) 328 { 329 ByteString aString; 330 for ( sal_uInt32 j = 0; nLen && ( j < ( nNumSize >> 1 ) ); j++ ) 331 { 332 for ( sal_uInt32 k = 0; k < 2; k++ ) 333 { 334 if ( nLen ) 335 { 336 sal_uInt8 nVal; 337 rIn >> nVal; 338 if ( ( nVal >> 4 ) > 9 ) 339 *pOut << (sal_uInt8)( ( nVal >> 4 ) + 'A' - 10 ); 340 else 341 *pOut << (sal_uInt8)( ( nVal >> 4 ) + '0' ); 342 343 if ( ( nVal & 0xf ) > 9 ) 344 *pOut << (sal_uInt8)( ( nVal & 0xf ) + 'A' - 10 ); 345 else 346 *pOut << (sal_uInt8)( ( nVal & 0xf ) + '0' ); 347 348 nLen--; 349 } 350 } 351 *pOut << (char)( ' ' ); 352 } 353 pOut->WriteLine( aString ); 354 } 355 } 356 } 357 else 358 { 359 ByteString aString( "Property" ); 360 aString.Append( ByteString::CreateFromInt32( i ) ); 361 aString.Append( ":" ); 362 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) ); 363 pOut->WriteLine( aString ); 364 } 365 } 366 } 367 368 delete pOut; 369 } 370 } 371 372 #endif 373 374 rIn.Seek( nFilePos ); 375 } 376 377 378 sal_Int32 DffPropertyReader::Fix16ToAngle( sal_Int32 nContent ) const 379 { 380 sal_Int32 nAngle = 0; 381 if ( nContent ) 382 { 383 nAngle = ( (sal_Int16)( nContent >> 16) * 100L ) + ( ( ( nContent & 0x0000ffff) * 100L ) >> 16 ); 384 nAngle = NormAngle360( -nAngle ); 385 } 386 return nAngle; 387 } 388 389 DffPropertyReader::~DffPropertyReader() 390 { 391 delete pDefaultPropSet; 392 } 393 394 //////////////////////////////////////////////////////////////////////////////////////////////////// 395 396 SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rRule ) 397 { 398 rIn >> rRule.nRuleId 399 >> rRule.nShapeA 400 >> rRule.nShapeB 401 >> rRule.nShapeC 402 >> rRule.ncptiA 403 >> rRule.ncptiB; 404 405 return rIn; 406 } 407 408 SvxMSDffSolverContainer::SvxMSDffSolverContainer() 409 { 410 } 411 412 SvxMSDffSolverContainer::~SvxMSDffSolverContainer() 413 { 414 for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)aCList.First(); 415 pPtr; pPtr = (SvxMSDffConnectorRule*)aCList.Next() ) 416 delete pPtr; 417 } 418 419 SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rContainer ) 420 { 421 DffRecordHeader aHd; 422 rIn >> aHd; 423 if ( aHd.nRecType == DFF_msofbtSolverContainer ) 424 { 425 DffRecordHeader aCRule; 426 while ( ( rIn.GetError() == 0 ) && ( rIn.Tell() < aHd.GetRecEndFilePos() ) ) 427 { 428 rIn >> aCRule; 429 if ( aCRule.nRecType == DFF_msofbtConnectorRule ) 430 { 431 SvxMSDffConnectorRule* pRule = new SvxMSDffConnectorRule; 432 rIn >> *pRule; 433 rContainer.aCList.Insert( pRule, LIST_APPEND ); 434 } 435 aCRule.SeekToEndOfRecord( rIn ); 436 } 437 } 438 return rIn; 439 } 440 441 void SvxMSDffManager::SolveSolver( const SvxMSDffSolverContainer& rSolver ) 442 { 443 sal_Int32 i, nCnt; 444 for ( i = 0, nCnt = rSolver.aCList.Count(); i < nCnt; i++ ) 445 { 446 SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rSolver.aCList.GetObject( i ); 447 if ( pPtr->pCObj ) 448 { 449 for ( int nN = 0; nN < 2; nN++ ) 450 { 451 SdrObject* pO; 452 sal_uInt32 nC, nSpFlags; 453 sal_Bool bTail; 454 if ( !nN ) 455 { 456 bTail = sal_True; 457 pO = pPtr->pAObj; 458 nC = pPtr->ncptiA; 459 nSpFlags = pPtr->nSpFlagsA; 460 } 461 else 462 { 463 bTail = sal_False; 464 pO = pPtr->pBObj; 465 nC = pPtr->ncptiB; 466 nSpFlags = pPtr->nSpFlagsB; 467 } 468 if ( pO ) 469 { 470 Any aAny; 471 SdrGluePoint aGluePoint; 472 Reference< XShape > aXShape( pO->getUnoShape(), UNO_QUERY ); 473 Reference< XShape > aXConnector( pPtr->pCObj->getUnoShape(), UNO_QUERY ); 474 SdrGluePointList* pList = pO->ForceGluePointList(); 475 476 sal_Bool bValidGluePoint = sal_False; 477 sal_Int32 nId = nC; 478 sal_uInt32 nInventor = pO->GetObjInventor(); 479 480 if( nInventor == SdrInventor ) 481 { 482 sal_uInt32 nObjId = pO->GetObjIdentifier(); 483 switch( nObjId ) 484 { 485 case OBJ_GRUP : 486 case OBJ_GRAF : 487 case OBJ_RECT : 488 case OBJ_TEXT : 489 case OBJ_PAGE : 490 case OBJ_TEXTEXT : 491 case OBJ_wegFITTEXT : 492 case OBJ_wegFITALLTEXT : 493 case OBJ_TITLETEXT : 494 case OBJ_OUTLINETEXT : 495 { 496 if ( nC & 1 ) 497 { 498 if ( nSpFlags & SP_FFLIPH ) 499 nC ^= 2; // 1 <-> 3 500 } 501 else 502 { 503 if ( nSpFlags & SP_FFLIPV ) 504 nC ^= 1; // 0 <-> 2 505 } 506 switch( nC ) 507 { 508 case 0 : 509 nId = 0; // SDRVERTALIGN_TOP; 510 break; 511 case 1 : 512 nId = 3; // SDRHORZALIGN_RIGHT; 513 break; 514 case 2 : 515 nId = 2; // SDRVERTALIGN_BOTTOM; 516 break; 517 case 3 : 518 nId = 1; // SDRHORZALIGN_LEFT; 519 break; 520 } 521 if ( nId <= 3 ) 522 bValidGluePoint = sal_True; 523 } 524 break; 525 case OBJ_POLY : 526 case OBJ_PLIN : 527 case OBJ_LINE : 528 case OBJ_PATHLINE : 529 case OBJ_PATHFILL : 530 case OBJ_FREELINE : 531 case OBJ_FREEFILL : 532 case OBJ_SPLNLINE : 533 case OBJ_SPLNFILL : 534 case OBJ_PATHPOLY : 535 case OBJ_PATHPLIN : 536 { 537 if ( pList && ( pList->GetCount() > nC ) ) 538 { 539 bValidGluePoint = sal_True; 540 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 ); 541 } 542 else 543 { 544 sal_Bool bNotFound = sal_True; 545 546 PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aXShape ) ); 547 sal_uInt16 k, j, nPolySize = aPolyPoly.Count(); 548 if ( nPolySize ) 549 { 550 sal_uInt32 nPointCount = 0; 551 Rectangle aBoundRect( aPolyPoly.GetBoundRect() ); 552 if ( aBoundRect.GetWidth() && aBoundRect.GetHeight() ) 553 { 554 for ( k = 0; bNotFound && ( k < nPolySize ); k++ ) 555 { 556 const Polygon& rPolygon = aPolyPoly.GetObject( k ); 557 for ( j = 0; bNotFound && ( j < rPolygon.GetSize() ); j++ ) 558 { 559 PolyFlags eFlags = rPolygon.GetFlags( j ); 560 if ( eFlags == POLY_NORMAL ) 561 { 562 if ( nC == nPointCount ) 563 { 564 const Point& rPoint = rPolygon.GetPoint( j ); 565 double fXRel = rPoint.X() - aBoundRect.Left(); 566 double fYRel = rPoint.Y() - aBoundRect.Top(); 567 sal_Int32 nWidth = aBoundRect.GetWidth(); 568 if ( !nWidth ) 569 nWidth = 1; 570 sal_Int32 nHeight= aBoundRect.GetHeight(); 571 if ( !nHeight ) 572 nHeight = 1; 573 fXRel /= (double)nWidth; 574 fXRel *= 10000; 575 fYRel /= (double)nHeight; 576 fYRel *= 10000; 577 aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) ); 578 aGluePoint.SetPercent( sal_True ); 579 aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT ); 580 aGluePoint.SetEscDir( SDRESC_SMART ); 581 nId = (sal_Int32)((*pList)[ pList->Insert( aGluePoint ) ].GetId() + 3 ); 582 bNotFound = sal_False; 583 } 584 nPointCount++; 585 } 586 } 587 } 588 } 589 } 590 if ( !bNotFound ) 591 { 592 bValidGluePoint = sal_True; 593 } 594 } 595 } 596 break; 597 598 case OBJ_CUSTOMSHAPE : 599 { 600 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pO)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); 601 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); 602 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) ); 603 sal_Int16 nGluePointType = EnhancedCustomShapeGluePointType::SEGMENTS; 604 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePointType ); 605 if ( pAny ) 606 *pAny >>= nGluePointType; 607 else 608 { 609 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 610 rtl::OUString sShapeType; 611 pAny = aGeometryItem.GetPropertyValueByName( sType ); 612 if ( pAny ) 613 *pAny >>= sShapeType; 614 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType ); 615 nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType ); 616 } 617 if ( nGluePointType == EnhancedCustomShapeGluePointType::CUSTOM ) 618 { 619 if ( pList && ( pList->GetCount() > nC ) ) 620 { 621 bValidGluePoint = sal_True; 622 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 ); 623 } 624 } 625 else if ( nGluePointType == EnhancedCustomShapeGluePointType::RECT ) 626 { 627 if ( nC & 1 ) 628 { 629 if ( nSpFlags & SP_FFLIPH ) 630 nC ^= 2; // 1 <-> 3 631 } 632 else 633 { 634 if ( nSpFlags & SP_FFLIPV ) 635 nC ^= 1; // 0 <-> 2 636 } 637 switch( nC ) 638 { 639 case 0 : 640 nId = 0; // SDRVERTALIGN_TOP; 641 break; 642 case 1 : 643 nId = 3; // SDRHORZALIGN_RIGHT; 644 break; 645 case 2 : 646 nId = 2; // SDRVERTALIGN_BOTTOM; 647 break; 648 case 3 : 649 nId = 1; // SDRHORZALIGN_LEFT; 650 break; 651 } 652 if ( nId <= 3 ) 653 bValidGluePoint = sal_True; 654 } 655 else if ( nGluePointType == EnhancedCustomShapeGluePointType::SEGMENTS ) 656 { 657 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) ); 658 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) ); 659 660 sal_uInt32 k, nPt = nC; 661 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments; 662 pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments ); 663 if ( pAny ) 664 { 665 if ( *pAny >>= aSegments ) 666 { 667 for ( nPt = 0, k = 1; nC && ( k < (sal_uInt32)aSegments.getLength() ); k++ ) 668 { 669 sal_Int16 j, nCnt2 = aSegments[ k ].Count; 670 if ( aSegments[ k ].Command != EnhancedCustomShapeSegmentCommand::UNKNOWN ) 671 { 672 for ( j = 0; nC && ( j < nCnt2 ); j++ ) 673 { 674 switch( aSegments[ k ].Command ) 675 { 676 case EnhancedCustomShapeSegmentCommand::ENDSUBPATH : 677 case EnhancedCustomShapeSegmentCommand::CLOSESUBPATH : 678 case EnhancedCustomShapeSegmentCommand::LINETO : 679 case EnhancedCustomShapeSegmentCommand::MOVETO : 680 { 681 nC--; 682 nPt++; 683 } 684 break; 685 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX : 686 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY : 687 break; 688 689 case EnhancedCustomShapeSegmentCommand::CURVETO : 690 { 691 nC--; 692 nPt += 3; 693 } 694 break; 695 696 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO : 697 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE : 698 { 699 nC--; 700 nPt += 3; 701 } 702 break; 703 case EnhancedCustomShapeSegmentCommand::ARCTO : 704 case EnhancedCustomShapeSegmentCommand::ARC : 705 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO : 706 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARC : 707 { 708 nC--; 709 nPt += 4; 710 } 711 break; 712 } 713 } 714 } 715 } 716 } 717 } 718 pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates ); 719 if ( pAny ) 720 { 721 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates; 722 *pAny >>= aCoordinates; 723 if ( nPt < (sal_uInt32)aCoordinates.getLength() ) 724 { 725 nId = 4; 726 com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPara = aCoordinates[ nPt ]; 727 sal_Int32 nX = 0, nY = 0; 728 if ( ( rPara.First.Value >>= nX ) && ( rPara.Second.Value >>= nY ) ) 729 { 730 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) ); 731 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints; 732 pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints ); 733 if ( pAny ) 734 *pAny >>= aGluePoints; 735 sal_Int32 nGluePoints = aGluePoints.getLength(); 736 aGluePoints.realloc( nGluePoints + 1 ); 737 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].First, nX ); 738 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].Second, nY ); 739 PropertyValue aProp; 740 aProp.Name = sGluePoints; 741 aProp.Value <<= aGluePoints; 742 aGeometryItem.SetPropertyValue( sPath, aProp ); 743 bValidGluePoint = sal_True; 744 ((SdrObjCustomShape*)pO)->SetMergedItem( aGeometryItem ); 745 SdrGluePointList* pLst = pO->ForceGluePointList(); 746 if ( pLst->GetCount() > nGluePoints ) 747 nId = (sal_Int32)((*pLst)[ (sal_uInt16)nGluePoints ].GetId() + 3 ); 748 } 749 } 750 } 751 } 752 } 753 break; 754 } 755 if ( bValidGluePoint ) 756 { 757 Reference< XPropertySet > xPropSet( aXConnector, UNO_QUERY ); 758 if ( xPropSet.is() ) 759 { 760 if ( nN ) 761 { 762 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "EndShape" ) ); 763 aAny <<= aXShape; 764 SetPropValue( aAny, xPropSet, aPropName, sal_True ); 765 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "EndGluePointIndex" ) ); 766 aAny <<= nId; 767 SetPropValue( aAny, xPropSet, aPropName, sal_True ); 768 } 769 else 770 { 771 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "StartShape" ) ); 772 aAny <<= aXShape; 773 SetPropValue( aAny, xPropSet, aPropName, sal_True ); 774 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "StartGluePointIndex" ) ); 775 aAny <<= nId; 776 SetPropValue( aAny, xPropSet, aPropName, sal_True ); 777 } 778 779 // Not sure what this is good for, repaint or broadcast of object change. 780 //( Thus i am adding repaint here 781 pO->SetChanged(); 782 pO->BroadcastObjectChange(); 783 } 784 } 785 } 786 } 787 } 788 } 789 } 790 } 791 792 //////////////////////////////////////////////////////////////////////////////////////////////////// 793 794 static basegfx::B2DPolygon GetLineArrow( const sal_Int32 nLineWidth, const MSO_LineEnd eLineEnd, 795 const MSO_LineEndWidth eLineWidth, const MSO_LineEndLength eLineLenght, 796 sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter, 797 String& rsArrowName, sal_Bool bScaleArrow ) 798 { 799 basegfx::B2DPolygon aRetval; 800 double fLineWidth = nLineWidth < 70 ? 70.0 : nLineWidth; 801 double fLenghtMul, fWidthMul; 802 sal_Int32 nLineNumber; 803 switch( eLineLenght ) 804 { 805 default : 806 case mso_lineMediumLenArrow : fLenghtMul = 3.0; nLineNumber = 2; break; 807 case mso_lineShortArrow : fLenghtMul = 2.0; nLineNumber = 1; break; 808 case mso_lineLongArrow : fLenghtMul = 5.0; nLineNumber = 3; break; 809 } 810 switch( eLineWidth ) 811 { 812 default : 813 case mso_lineMediumWidthArrow : fWidthMul = 3.0; nLineNumber += 3; break; 814 case mso_lineNarrowArrow : fWidthMul = 2.0; break; 815 case mso_lineWideArrow : fWidthMul = 5.0; nLineNumber += 6; break; 816 } 817 818 if ( bScaleArrow ) // #i33630 arrows imported from Word are too big 819 { 820 fWidthMul /= 1.75; 821 fLenghtMul/= 1.75; 822 } 823 824 rbArrowCenter = sal_False; 825 switch ( eLineEnd ) 826 { 827 case mso_lineArrowEnd : 828 { 829 basegfx::B2DPolygon aTriangle; 830 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, 0.0 )); 831 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth )); 832 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth )); 833 aTriangle.setClosed(true); 834 aRetval = aTriangle; 835 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowEnd " ), RTL_TEXTENCODING_UTF8 ); 836 } 837 break; 838 839 case mso_lineArrowOpenEnd : 840 { 841 switch( eLineLenght ) 842 { 843 default : 844 case mso_lineMediumLenArrow : fLenghtMul = 4.5; break; 845 case mso_lineShortArrow : fLenghtMul = 3.5; break; 846 case mso_lineLongArrow : fLenghtMul = 6.0; break; 847 } 848 switch( eLineWidth ) 849 { 850 default : 851 case mso_lineMediumWidthArrow : fWidthMul = 4.5; break; 852 case mso_lineNarrowArrow : fWidthMul = 3.5; break; 853 case mso_lineWideArrow : fWidthMul = 6.0; break; 854 } 855 basegfx::B2DPolygon aTriangle; 856 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 )); 857 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth * 0.91 )); 858 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.85, fLenghtMul * fLineWidth )); 859 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, fLenghtMul * fLineWidth * 0.36 )); 860 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.15, fLenghtMul * fLineWidth )); 861 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.91 )); 862 aTriangle.setClosed(true); 863 aRetval = aTriangle; 864 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOpenEnd " ), RTL_TEXTENCODING_UTF8 ); 865 } 866 break; 867 case mso_lineArrowStealthEnd : 868 { 869 basegfx::B2DPolygon aTriangle; 870 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 )); 871 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth )); 872 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth * 0.60 )); 873 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth )); 874 aTriangle.setClosed(true); 875 aRetval = aTriangle; 876 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowStealthEnd " ), RTL_TEXTENCODING_UTF8 ); 877 } 878 break; 879 case mso_lineArrowDiamondEnd : 880 { 881 basegfx::B2DPolygon aTriangle; 882 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 )); 883 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth * 0.50 )); 884 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth )); 885 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.50 )); 886 aTriangle.setClosed(true); 887 aRetval = aTriangle; 888 rbArrowCenter = sal_True; 889 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowDiamondEnd " ), RTL_TEXTENCODING_UTF8 ); 890 } 891 break; 892 case mso_lineArrowOvalEnd : 893 { 894 aRetval = XPolygon( Point( (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 0 ), 895 (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 896 (sal_Int32)( fLenghtMul * fLineWidth * 0.50 ), 0, 3600 ).getB2DPolygon(); 897 rbArrowCenter = sal_True; 898 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOvalEnd " ), RTL_TEXTENCODING_UTF8 ); 899 } 900 break; 901 default: break; 902 } 903 rsArrowName.Append( String::CreateFromInt32( nLineNumber ) ); 904 rnArrowWidth = (sal_Int32)( fLineWidth * fWidthMul ); 905 906 return aRetval; 907 } 908 909 void DffPropertyReader::ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const // #i28269# 910 { 911 sal_uInt32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash )); 912 913 if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( eShapeType )) 914 { 915 nLineFlags &= ~0x08; 916 } 917 918 if ( nLineFlags & 8 ) 919 { 920 // Linienattribute 921 sal_Int32 nLineWidth = (sal_Int32)GetPropertyValue( DFF_Prop_lineWidth, 9525 ); 922 923 // support LineCap 924 const MSO_LineCap eLineCap((MSO_LineCap)GetPropertyValue(DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare)); 925 926 switch(eLineCap) 927 { 928 default: /* case mso_lineEndCapFlat */ 929 { 930 // no need to set, it is the default. If this changes, this needs to be activated 931 // rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_BUTT)); 932 break; 933 } 934 case mso_lineEndCapRound: 935 { 936 rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_ROUND)); 937 break; 938 } 939 case mso_lineEndCapSquare: 940 { 941 rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_SQUARE)); 942 break; 943 } 944 } 945 946 MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid ); 947 if ( eLineDashing == mso_lineSolid ) 948 rSet.Put(XLineStyleItem( XLINE_SOLID ) ); 949 else 950 { 951 952 XDashStyle eDash = XDASH_RECT; 953 sal_uInt16 nDots = 1; 954 sal_uInt32 nDotLen = nLineWidth / 360; 955 sal_uInt16 nDashes = 0; 956 sal_uInt32 nDashLen = ( 8 * nLineWidth ) / 360; 957 sal_uInt32 nDistance = ( 3 * nLineWidth ) / 360; 958 959 switch ( eLineDashing ) 960 { 961 default: 962 case mso_lineDotSys : 963 { 964 nDots = 1; 965 nDashes = 0; 966 nDistance = nDotLen; 967 } 968 break; 969 970 case mso_lineDashGEL : 971 { 972 nDots = 0; 973 nDashes = 1; 974 nDashLen = ( 4 * nLineWidth ) / 360; 975 } 976 break; 977 978 case mso_lineDashDotGEL : 979 { 980 nDots = 1; 981 nDashes = 1; 982 nDashLen = ( 4 * nLineWidth ) / 360; 983 } 984 break; 985 986 case mso_lineLongDashGEL : 987 { 988 nDots = 0; 989 nDashes = 1; 990 } 991 break; 992 993 case mso_lineLongDashDotGEL : 994 { 995 nDots = 1; 996 nDashes = 1; 997 } 998 break; 999 1000 case mso_lineLongDashDotDotGEL: 1001 { 1002 nDots = 2; 1003 nDashes = 1; 1004 } 1005 break; 1006 } 1007 1008 rSet.Put( XLineDashItem( String(), XDash( eDash, nDots, nDotLen, nDashes, nDashLen, nDistance ) ) ); 1009 rSet.Put( XLineStyleItem( XLINE_DASH ) ); 1010 } 1011 rSet.Put( XLineColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_lineColor ), DFF_Prop_lineColor ) ) ); 1012 if ( IsProperty( DFF_Prop_lineOpacity ) ) 1013 { 1014 double nTrans = GetPropertyValue(DFF_Prop_lineOpacity, 0x10000); 1015 nTrans = (nTrans * 100) / 65536; 1016 rSet.Put(XLineTransparenceItem( 1017 sal_uInt16(100 - ::rtl::math::round(nTrans)))); 1018 } 1019 1020 rManager.ScaleEmu( nLineWidth ); 1021 rSet.Put( XLineWidthItem( nLineWidth ) ); 1022 1023 // SJ: LineJoint (setting each time a line is set, because our internal joint type has another default) 1024 MSO_LineJoin eLineJointDefault = mso_lineJoinMiter; 1025 if ( eShapeType == mso_sptMin ) 1026 eLineJointDefault = mso_lineJoinRound; 1027 MSO_LineJoin eLineJoint = (MSO_LineJoin)GetPropertyValue( DFF_Prop_lineJoinStyle, eLineJointDefault ); 1028 XLineJoint eXLineJoint( XLINEJOINT_MITER ); 1029 if ( eLineJoint == mso_lineJoinBevel ) 1030 eXLineJoint = XLINEJOINT_BEVEL; 1031 else if ( eLineJoint == mso_lineJoinRound ) 1032 eXLineJoint = XLINEJOINT_ROUND; 1033 rSet.Put( XLineJointItem( eXLineJoint ) ); 1034 1035 if ( nLineFlags & 0x10 ) 1036 { 1037 sal_Bool bScaleArrows = rManager.pSdrModel->GetScaleUnit() == MAP_TWIP; 1038 /////////////// 1039 // LineStart // 1040 /////////////// 1041 if ( IsProperty( DFF_Prop_lineStartArrowhead ) ) 1042 { 1043 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineStartArrowhead ); 1044 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineStartArrowWidth, mso_lineMediumWidthArrow ); 1045 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineStartArrowLength, mso_lineMediumLenArrow ); 1046 1047 sal_Int32 nArrowWidth; 1048 sal_Bool bArrowCenter; 1049 String aArrowName; 1050 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows )); 1051 1052 rSet.Put( XLineStartWidthItem( nArrowWidth ) ); 1053 rSet.Put( XLineStartItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) ); 1054 rSet.Put( XLineStartCenterItem( bArrowCenter ) ); 1055 } 1056 ///////////// 1057 // LineEnd // 1058 ///////////// 1059 if ( IsProperty( DFF_Prop_lineEndArrowhead ) ) 1060 { 1061 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineEndArrowhead ); 1062 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineEndArrowWidth, mso_lineMediumWidthArrow ); 1063 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineEndArrowLength, mso_lineMediumLenArrow ); 1064 1065 sal_Int32 nArrowWidth; 1066 sal_Bool bArrowCenter; 1067 String aArrowName; 1068 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows )); 1069 1070 rSet.Put( XLineEndWidthItem( nArrowWidth ) ); 1071 rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) ); 1072 rSet.Put( XLineEndCenterItem( bArrowCenter ) ); 1073 } 1074 1075 // this was used to at least adapt the lineDash to the lineCap before lineCap was 1076 // supported, so with supporting lineCap this is no longer needed 1077 //if ( IsProperty( DFF_Prop_lineEndCapStyle ) ) 1078 //{ 1079 // MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle ); 1080 // const SfxPoolItem* pPoolItem = NULL; 1081 // if ( rSet.GetItemState( XATTR_LINEDASH, sal_False, &pPoolItem ) == SFX_ITEM_SET ) 1082 // { 1083 // XDashStyle eNewStyle = XDASH_RECT; 1084 // if ( eLineCap == mso_lineEndCapRound ) 1085 // eNewStyle = XDASH_ROUND; 1086 // const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue(); 1087 // if ( rOldDash.GetDashStyle() != eNewStyle ) 1088 // { 1089 // XDash aNew( rOldDash ); 1090 // aNew.SetDashStyle( eNewStyle ); 1091 // rSet.Put( XLineDashItem( XubString(), aNew ) ); 1092 // } 1093 // } 1094 //} 1095 } 1096 } 1097 else 1098 rSet.Put( XLineStyleItem( XLINE_NONE ) ); 1099 } 1100 1101 struct ShadeColor 1102 { 1103 Color aColor; 1104 double fDist; 1105 1106 ShadeColor( const Color& rC, double fR ) : aColor( rC ), fDist( fR ) {}; 1107 }; 1108 1109 void GetShadeColors( const SvxMSDffManager& rManager, const DffPropertyReader& rProperties, SvStream& rIn, std::vector< ShadeColor >& rShadeColors ) 1110 { 1111 sal_uInt32 nPos = rIn.Tell(); 1112 if ( rProperties.IsProperty( DFF_Prop_fillShadeColors ) ) 1113 { 1114 if ( rProperties.SeekToContent( DFF_Prop_fillShadeColors, rIn ) ) 1115 { 1116 sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0; 1117 rIn >> nNumElem >> nNumElemReserved >> nSize; 1118 for ( ; i < nNumElem; i++ ) 1119 { 1120 sal_Int32 nColor; 1121 sal_Int32 nDist; 1122 1123 rIn >> nColor >> nDist; 1124 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( nColor, DFF_Prop_fillColor ), 1.0 - ( nDist / 65536.0 ) ) ); 1125 } 1126 } 1127 } 1128 if ( !rShadeColors.size() ) 1129 { 1130 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ), 0 ) ); 1131 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ), 1 ) ); 1132 } 1133 rIn.Seek( nPos ); 1134 } 1135 1136 struct QuantErr 1137 { 1138 double fRed; 1139 double fGreen; 1140 double fBlue; 1141 1142 QuantErr() : fRed( 0.0 ), fGreen( 0.0 ), fBlue( 0.0 ){}; 1143 }; 1144 1145 void ApplyRectangularGradientAsBitmap( const SvxMSDffManager& rManager, SvStream& rIn, SfxItemSet& rSet, const std::vector< ShadeColor >& rShadeColors, const DffObjData& rObjData, sal_Int32 nFix16Angle ) 1146 { 1147 Size aBitmapSizePixel( static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetWidth() / 2540.0 ) * 90.0 ), // we will create a bitmap with 90 dpi 1148 static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetHeight() / 2540.0 ) * 90.0 ) ); 1149 if ( aBitmapSizePixel.Width() && aBitmapSizePixel.Height() && ( aBitmapSizePixel.Width() <= 1024 ) && ( aBitmapSizePixel.Height() <= 1024 ) ) 1150 { 1151 // std::vector< QuantErr > aQuantErrCurrScan( aBitmapSizePixel.Width() + 1 ); 1152 // std::vector< QuantErr > aQuantErrNextScan( aBitmapSizePixel.Width() + 1 ); 1153 1154 double fFocusX = rManager.GetPropertyValue( DFF_Prop_fillToRight, 0 ) / 65536.0; 1155 double fFocusY = rManager.GetPropertyValue( DFF_Prop_fillToBottom, 0 ) / 65536.0; 1156 1157 Bitmap aBitmap( aBitmapSizePixel, 24 ); 1158 BitmapWriteAccess* pAcc = aBitmap.AcquireWriteAccess(); 1159 if ( pAcc ) 1160 { 1161 sal_Int32 nX, nY; 1162 for ( nY = 0; nY < aBitmapSizePixel.Height(); nY++ ) 1163 { 1164 for ( nX = 0; nX < aBitmapSizePixel.Width(); nX++ ) 1165 { 1166 double fX = static_cast< double >( nX ) / aBitmapSizePixel.Width(); 1167 double fY = static_cast< double >( nY ) / aBitmapSizePixel.Height(); 1168 1169 double fD, fDist; 1170 if ( fX < fFocusX ) 1171 { 1172 if ( fY < fFocusY ) 1173 { 1174 if ( fX > fY ) 1175 fDist = fY, fD = fFocusY; 1176 else 1177 fDist = fX, fD = fFocusX; 1178 } 1179 else 1180 { 1181 if ( fX > ( 1 - fY ) ) 1182 fDist = ( 1 - fY ), fD = 1 - fFocusY; 1183 else 1184 fDist = fX, fD = fFocusX; 1185 } 1186 } 1187 else 1188 { 1189 if ( fY < fFocusY ) 1190 { 1191 if ( ( 1 - fX ) > fY ) 1192 fDist = fY, fD = fFocusY; 1193 else 1194 fDist = ( 1 - fX ), fD = 1 - fFocusX; 1195 } 1196 else 1197 { 1198 if ( ( 1 - fX ) > ( 1 - fY ) ) 1199 fDist = ( 1 - fY ), fD = 1 - fFocusY; 1200 else 1201 fDist = ( 1 - fX ), fD = 1 - fFocusX; 1202 } 1203 } 1204 if ( fD != 0.0 ) 1205 fDist /= fD; 1206 1207 std::vector< ShadeColor >::const_iterator aIter( rShadeColors.begin() ); 1208 double fA = 0.0; 1209 Color aColorA = aIter->aColor; 1210 double fB = 1.0; 1211 Color aColorB( aColorA ); 1212 while ( aIter != rShadeColors.end() ) 1213 { 1214 if ( aIter->fDist <= fDist ) 1215 { 1216 if ( aIter->fDist >= fA ) 1217 { 1218 fA = aIter->fDist; 1219 aColorA = aIter->aColor; 1220 } 1221 } 1222 if ( aIter->fDist > fDist ) 1223 { 1224 if ( aIter->fDist <= fB ) 1225 { 1226 fB = aIter->fDist; 1227 aColorB = aIter->aColor; 1228 } 1229 } 1230 aIter++; 1231 } 1232 double fRed = aColorA.GetRed(), fGreen = aColorA.GetGreen(), fBlue = aColorA.GetBlue(); 1233 double fD1 = fB - fA; 1234 if ( fD1 != 0.0 ) 1235 { 1236 fRed += ( ( ( fDist - fA ) * ( aColorB.GetRed() - aColorA.GetRed() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fRed; 1237 fGreen += ( ( ( fDist - fA ) * ( aColorB.GetGreen() - aColorA.GetGreen() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fGreen; 1238 fBlue += ( ( ( fDist - fA ) * ( aColorB.GetBlue() - aColorA.GetBlue() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fBlue; 1239 } 1240 sal_Int16 nRed = static_cast< sal_Int16 >( fRed + 0.5 ); 1241 sal_Int16 nGreen = static_cast< sal_Int16 >( fGreen + 0.5 ); 1242 sal_Int16 nBlue = static_cast< sal_Int16 >( fBlue + 0.5 ); 1243 /* 1244 double fErr = fRed - nRed; 1245 aQuantErrCurrScan[ nX + 1 ].fRed += 7.0 * fErr / 16.0; 1246 if ( nX ) 1247 aQuantErrNextScan[ nX - 1 ].fRed += 3.0 * fErr / 16.0; 1248 aQuantErrNextScan[ nX ].fRed += 5.0 * fErr / 16.0; 1249 aQuantErrNextScan[ nX + 1 ].fRed += 1.0 * fErr / 16.0; 1250 1251 fErr = fGreen - nGreen; 1252 aQuantErrCurrScan[ nX + 1 ].fGreen += 7.0 * fErr / 16.0; 1253 if ( nX ) 1254 aQuantErrNextScan[ nX - 1 ].fGreen += 3.0 * fErr / 16.0; 1255 aQuantErrNextScan[ nX ].fGreen += 5.0 * fErr / 16.0; 1256 aQuantErrNextScan[ nX + 1 ].fGreen += 1.0 * fErr / 16.0; 1257 1258 fErr = fBlue - nBlue; 1259 aQuantErrCurrScan[ nX + 1 ].fBlue += 7.0 * fErr / 16.0; 1260 if ( nX ) 1261 aQuantErrNextScan[ nX - 1 ].fBlue += 3.0 * fErr / 16.0; 1262 aQuantErrNextScan[ nX ].fBlue += 5.0 * fErr / 16.0; 1263 aQuantErrNextScan[ nX + 1 ].fBlue += 1.0 * fErr / 16.0; 1264 */ 1265 if ( nRed < 0 ) 1266 nRed = 0; 1267 if ( nRed > 255 ) 1268 nRed = 255; 1269 if ( nGreen < 0 ) 1270 nGreen = 0; 1271 if ( nGreen > 255 ) 1272 nGreen = 255; 1273 if ( nBlue < 0 ) 1274 nBlue = 0; 1275 if ( nBlue > 255 ) 1276 nBlue = 255; 1277 1278 pAcc->SetPixel( nY, nX, BitmapColor( static_cast< sal_Int8 >( nRed ), static_cast< sal_Int8 >( nGreen ), static_cast< sal_Int8 >( nBlue ) ) ); 1279 } 1280 /* 1281 aQuantErrCurrScan.swap( aQuantErrNextScan ); 1282 std::vector< QuantErr >::iterator aIter( aQuantErrNextScan.begin() ); 1283 while( aIter != aQuantErrNextScan.end() ) 1284 { 1285 *aIter = QuantErr(); 1286 aIter++; 1287 } 1288 */ 1289 } 1290 aBitmap.ReleaseAccess( pAcc ); 1291 1292 if ( nFix16Angle ) 1293 { 1294 sal_Bool bRotateWithShape = sal_True; // sal_True seems to be default 1295 sal_uInt32 nPos = rIn.Tell(); 1296 if ( const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.SeekToContent( rIn, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) ) 1297 { 1298 const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.Current()->SeekToBegOfRecord( rIn ); 1299 DffPropertyReader aSecPropSet( rManager ); 1300 aSecPropSet.ReadPropSet( rIn, NULL ); 1301 sal_Int32 nSecFillProperties = aSecPropSet.GetPropertyValue( DFF_Prop_fNoFillHitTest, 0x200020 ); 1302 bRotateWithShape = ( nSecFillProperties & 0x0020 ); 1303 } 1304 rIn.Seek( nPos ); 1305 if ( bRotateWithShape ) 1306 { 1307 aBitmap.Rotate( nFix16Angle / 10, rShadeColors[ 0 ].aColor ); 1308 1309 sal_uLong nMirrorFlags = BMP_MIRROR_NONE; 1310 if ( rObjData.nSpFlags & SP_FFLIPV ) 1311 nMirrorFlags |= BMP_MIRROR_VERT; 1312 if ( rObjData.nSpFlags & SP_FFLIPH ) 1313 nMirrorFlags |= BMP_MIRROR_HORZ; 1314 if ( nMirrorFlags != BMP_MIRROR_NONE ) 1315 aBitmap.Mirror( nMirrorFlags ); 1316 } 1317 } 1318 1319 rSet.Put(XFillBmpTileItem(false)); 1320 rSet.Put(XFillBitmapItem(String(), Graphic(aBitmap))); 1321 } 1322 } 1323 } 1324 1325 void DffPropertyReader::ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const 1326 { 1327 sal_uInt32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest )); 1328 1329 std::vector< ShadeColor > aShadeColors; 1330 GetShadeColors( rManager, *this, rIn, aShadeColors ); 1331 1332 if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType )) 1333 { 1334 nFillFlags &= ~0x10; 1335 } 1336 1337 if ( nFillFlags & 0x10 ) 1338 { 1339 MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid ); 1340 XFillStyle eXFill = XFILL_NONE; 1341 switch( eMSO_FillType ) 1342 { 1343 case mso_fillSolid : // Fill with a solid color 1344 eXFill = XFILL_SOLID; 1345 break; 1346 case mso_fillPattern : // Fill with a pattern (bitmap) 1347 case mso_fillTexture : // A texture (pattern with its own color map) 1348 case mso_fillPicture : // Center a picture in the shape 1349 eXFill = XFILL_BITMAP; 1350 break; 1351 case mso_fillShadeCenter : // Shade from bounding rectangle to end point 1352 { 1353 if ( rObjData.aBoundRect.IsEmpty() )// size of object needed to be able 1354 eXFill = XFILL_GRADIENT; // to create a bitmap substitution 1355 else 1356 eXFill = XFILL_BITMAP; 1357 } 1358 break; 1359 case mso_fillShade : // Shade from start to end points 1360 case mso_fillShadeShape : // Shade from shape outline to end point 1361 case mso_fillShadeScale : // Similar to mso_fillShade, but the fillAngle 1362 case mso_fillShadeTitle : // special type - shade to title --- for PP 1363 eXFill = XFILL_GRADIENT; 1364 break; 1365 // case mso_fillBackground : // Use the background fill color/pattern 1366 default: break; 1367 } 1368 rSet.Put( XFillStyleItem( eXFill ) ); 1369 1370 if (IsProperty(DFF_Prop_fillOpacity)) 1371 { 1372 double nTrans = GetPropertyValue(DFF_Prop_fillOpacity); 1373 nTrans = (nTrans * 100) / 65536; 1374 rSet.Put(XFillTransparenceItem( 1375 sal_uInt16(100 - ::rtl::math::round(nTrans)))); 1376 } 1377 1378 if ( ( eMSO_FillType == mso_fillShadeCenter ) && ( eXFill == XFILL_BITMAP ) ) 1379 { 1380 ApplyRectangularGradientAsBitmap( rManager, rIn, rSet, aShadeColors, rObjData, mnFix16Angle ); 1381 } 1382 else if ( eXFill == XFILL_GRADIENT ) 1383 { 1384 sal_Int32 nAngle = 3600 - ( ( Fix16ToAngle( GetPropertyValue( DFF_Prop_fillAngle, 0 ) ) + 5 ) / 10 ); 1385 1386 // Rotationswinkel in Bereich zwingen 1387 while ( nAngle >= 3600 ) 1388 nAngle -= 3600; 1389 while ( nAngle < 0 ) 1390 nAngle += 3600; 1391 1392 sal_Int32 nFocus = GetPropertyValue( DFF_Prop_fillFocus, 0 ); 1393 XGradientStyle eGrad = XGRAD_LINEAR; 1394 sal_Int32 nChgColors = 0; 1395 1396 if ( nFocus < 0 ) // Bei negativem Focus sind die Farben zu tauschen 1397 { 1398 nFocus =- nFocus; 1399 nChgColors ^= 1; 1400 } 1401 if( nFocus > 40 && nFocus < 60 ) 1402 { 1403 eGrad = XGRAD_AXIAL; // Besser gehts leider nicht 1404 } 1405 1406 sal_uInt16 nFocusX = (sal_uInt16)nFocus; 1407 sal_uInt16 nFocusY = (sal_uInt16)nFocus; 1408 1409 switch( eMSO_FillType ) 1410 { 1411 case mso_fillShadeShape : 1412 { 1413 eGrad = XGRAD_RECT; 1414 nFocusY = nFocusX = 50; 1415 nChgColors ^= 1; 1416 } 1417 break; 1418 case mso_fillShadeCenter : 1419 { 1420 eGrad = XGRAD_RECT; 1421 nFocusX = ( IsProperty( DFF_Prop_fillToRight ) ) ? 100 : 0; 1422 nFocusY = ( IsProperty( DFF_Prop_fillToBottom ) ) ? 100 : 0; 1423 nChgColors ^= 1; 1424 } 1425 break; 1426 default: break; 1427 } 1428 Color aCol1( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ) ); 1429 Color aCol2( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ) ); 1430 1431 if ( nChgColors ) 1432 { 1433 Color aZwi( aCol1 ); 1434 aCol1 = aCol2; 1435 aCol2 = aZwi; 1436 } 1437 XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY ); 1438 aGrad.SetStartIntens( 100 ); 1439 aGrad.SetEndIntens( 100 ); 1440 rSet.Put( XFillGradientItem( String(), aGrad ) ); 1441 } 1442 else if ( eXFill == XFILL_BITMAP ) 1443 { 1444 if( IsProperty( DFF_Prop_fillBlip ) ) 1445 { 1446 Graphic aGraf; 1447 // first try to get BLIP from cache 1448 sal_Bool bOK = rManager.GetBLIP( GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL ); 1449 // then try directly from stream (i.e. Excel chart hatches/bitmaps) 1450 if ( !bOK ) 1451 bOK = SeekToContent( DFF_Prop_fillBlip, rIn ) && rManager.GetBLIPDirect( rIn, aGraf, NULL ); 1452 if ( bOK ) 1453 { 1454 if ( eMSO_FillType == mso_fillPattern ) 1455 { 1456 Color aCol1( COL_WHITE ), aCol2( COL_WHITE ); 1457 1458 if ( IsProperty( DFF_Prop_fillColor ) ) 1459 aCol1 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor ); 1460 1461 if ( IsProperty( DFF_Prop_fillBackColor ) ) 1462 aCol2 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor ), DFF_Prop_fillBackColor ); 1463 1464 rSet.Put(XFillBitmapItem(String(), aGraf)); 1465 } 1466 else if ( eMSO_FillType == mso_fillTexture ) 1467 { 1468 rSet.Put(XFillBmpTileItem(true)); 1469 rSet.Put(XFillBitmapItem(String(), aGraf)); 1470 rSet.Put(XFillBmpSizeXItem(GetPropertyValue(DFF_Prop_fillWidth, 0) / 360)); 1471 rSet.Put(XFillBmpSizeYItem(GetPropertyValue(DFF_Prop_fillHeight, 0) / 360)); 1472 rSet.Put(XFillBmpSizeLogItem(true)); 1473 } 1474 else 1475 { 1476 rSet.Put(XFillBitmapItem(String(), aGraf)); 1477 rSet.Put(XFillBmpTileItem(false)); 1478 } 1479 } 1480 } 1481 } 1482 } 1483 else 1484 rSet.Put( XFillStyleItem( XFILL_NONE ) ); 1485 } 1486 1487 void DffPropertyReader::ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const 1488 { 1489 // sal_uInt32 nTextFlags = aTextObj.GetTextFlags(); 1490 sal_Bool bVerticalText = sal_False; 1491 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ) / 360; // 0.25 cm (emu) 1492 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ) / 360; // 0.25 cm (emu) 1493 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ) / 360; // 0.13 cm (emu) 1494 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ) /360; // 0.13 cm (emu) 1495 1496 SdrTextVertAdjust eTVA; 1497 SdrTextHorzAdjust eTHA; 1498 1499 if ( IsProperty( DFF_Prop_txflTextFlow ) ) 1500 { 1501 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF ); 1502 switch( eTextFlow ) 1503 { 1504 case mso_txflTtoBA : /* #68110# */ // Top to Bottom @-font, oben -> unten 1505 case mso_txflTtoBN : // Top to Bottom non-@, oben -> unten 1506 case mso_txflVertN : // Vertical, non-@, oben -> unten 1507 bVerticalText = sal_True; // nTextRotationAngle += 27000; 1508 break; 1509 default: break; 1510 } 1511 } 1512 sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); 1513 if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) ) 1514 bVerticalText = !bVerticalText; 1515 1516 if ( bVerticalText ) 1517 { 1518 eTVA = SDRTEXTVERTADJUST_BLOCK; 1519 eTHA = SDRTEXTHORZADJUST_CENTER; 1520 1521 // Textverankerung lesen 1522 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); 1523 1524 switch( eTextAnchor ) 1525 { 1526 case mso_anchorTop: 1527 case mso_anchorTopCentered: 1528 case mso_anchorTopBaseline: 1529 case mso_anchorTopCenteredBaseline: 1530 eTHA = SDRTEXTHORZADJUST_RIGHT; 1531 break; 1532 1533 case mso_anchorMiddle : 1534 case mso_anchorMiddleCentered: 1535 eTHA = SDRTEXTHORZADJUST_CENTER; 1536 break; 1537 1538 case mso_anchorBottom: 1539 case mso_anchorBottomCentered: 1540 case mso_anchorBottomBaseline: 1541 case mso_anchorBottomCenteredBaseline: 1542 eTHA = SDRTEXTHORZADJUST_LEFT; 1543 break; 1544 } 1545 // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction 1546 switch ( eTextAnchor ) 1547 { 1548 case mso_anchorTopCentered : 1549 case mso_anchorMiddleCentered : 1550 case mso_anchorBottomCentered : 1551 case mso_anchorTopCenteredBaseline: 1552 case mso_anchorBottomCenteredBaseline: 1553 eTVA = SDRTEXTVERTADJUST_CENTER; 1554 break; 1555 1556 default : 1557 eTVA = SDRTEXTVERTADJUST_TOP; 1558 break; 1559 } 1560 } 1561 else 1562 { 1563 eTVA = SDRTEXTVERTADJUST_CENTER; 1564 eTHA = SDRTEXTHORZADJUST_BLOCK; 1565 1566 // Textverankerung lesen 1567 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); 1568 1569 switch( eTextAnchor ) 1570 { 1571 case mso_anchorTop: 1572 case mso_anchorTopCentered: 1573 case mso_anchorTopBaseline: 1574 case mso_anchorTopCenteredBaseline: 1575 eTVA = SDRTEXTVERTADJUST_TOP; 1576 break; 1577 1578 case mso_anchorMiddle : 1579 case mso_anchorMiddleCentered: 1580 eTVA = SDRTEXTVERTADJUST_CENTER; 1581 break; 1582 1583 case mso_anchorBottom: 1584 case mso_anchorBottomCentered: 1585 case mso_anchorBottomBaseline: 1586 case mso_anchorBottomCenteredBaseline: 1587 eTVA = SDRTEXTVERTADJUST_BOTTOM; 1588 break; 1589 } 1590 // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction 1591 switch ( eTextAnchor ) 1592 { 1593 case mso_anchorTopCentered : 1594 case mso_anchorMiddleCentered : 1595 case mso_anchorBottomCentered : 1596 case mso_anchorTopCenteredBaseline: 1597 case mso_anchorBottomCenteredBaseline: 1598 eTHA = SDRTEXTHORZADJUST_CENTER; // the text has to be displayed using the full width; 1599 break; 1600 1601 default : 1602 eTHA = SDRTEXTHORZADJUST_LEFT; 1603 break; 1604 } 1605 } 1606 rSet.Put( SvxFrameDirectionItem( bVerticalText ? FRMDIR_VERT_TOP_RIGHT : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) ); 1607 1608 rSet.Put( SdrTextVertAdjustItem( eTVA ) ); 1609 rSet.Put( SdrTextHorzAdjustItem( eTHA ) ); 1610 1611 rSet.Put( SdrTextLeftDistItem( nTextLeft ) ); 1612 rSet.Put( SdrTextRightDistItem( nTextRight ) ); 1613 rSet.Put( SdrTextUpperDistItem( nTextTop ) ); 1614 rSet.Put( SdrTextLowerDistItem( nTextBottom ) ); 1615 1616 rSet.Put( SdrTextWordWrapItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_True : sal_False ) ); 1617 rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) ); 1618 1619 // rSet.Put( SdrTextAutoGrowWidthItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_False : sal_True ) ); 1620 // rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) ); 1621 } 1622 1623 void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const 1624 { 1625 1626 sal_uInt32 nAdjustmentsWhichNeedsToBeConverted = 0; 1627 1628 /////////////////////////////////////// 1629 // creating SdrCustomShapeGeometryItem // 1630 /////////////////////////////////////// 1631 typedef uno::Sequence< beans::PropertyValue > PropSeq; 1632 typedef std::vector< beans::PropertyValue > PropVec; 1633 typedef PropVec::iterator PropVecIter; 1634 PropVecIter aIter; 1635 PropVecIter aEnd; 1636 1637 1638 // aPropVec will be filled with all PropertyValues 1639 PropVec aPropVec; 1640 PropertyValue aProp; 1641 1642 ///////////////////////////////////////////////////////////////////// 1643 // "Type" property, including the predefined CustomShape type name // 1644 ///////////////////////////////////////////////////////////////////// 1645 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 1646 aProp.Name = sType; 1647 aProp.Value <<= EnhancedCustomShapeTypeNames::Get( rObjData.eShapeType ); 1648 aPropVec.push_back( aProp ); 1649 1650 /* 1651 ///////////////// 1652 // "MirroredX" // 1653 ///////////////// 1654 if ( nShapeFlags & SP_FFLIPH ) 1655 { 1656 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) ); 1657 sal_Bool bMirroredX = sal_True; 1658 aProp.Name = sMirroredX; 1659 aProp.Value <<= bMirroredX; 1660 aPropVec.push_back( aProp ); 1661 } 1662 ///////////////// 1663 // "MirroredY" // 1664 ///////////////// 1665 if ( nShapeFlags & SP_FFLIPV ) 1666 { 1667 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) ); 1668 sal_Bool bMirroredY = sal_True; 1669 aProp.Name = sMirroredY; 1670 aProp.Value <<= bMirroredY; 1671 aPropVec.push_back( aProp ); 1672 } 1673 */ 1674 /////////////// 1675 // "ViewBox" // 1676 /////////////// 1677 1678 sal_Int32 nCoordWidth = 21600; // needed to replace handle type center with absolute value 1679 sal_Int32 nCoordHeight= 21600; 1680 if ( IsProperty( DFF_Prop_geoLeft ) || IsProperty( DFF_Prop_geoTop ) || IsProperty( DFF_Prop_geoRight ) || IsProperty( DFF_Prop_geoBottom ) ) 1681 { 1682 com::sun::star::awt::Rectangle aViewBox; 1683 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) ); 1684 aViewBox.X = GetPropertyValue( DFF_Prop_geoLeft, 0 ); 1685 aViewBox.Y = GetPropertyValue( DFF_Prop_geoTop, 0 ); 1686 aViewBox.Width = nCoordWidth = ((sal_Int32)GetPropertyValue( DFF_Prop_geoRight, 21600 ) ) - aViewBox.X; 1687 aViewBox.Height = nCoordHeight = ((sal_Int32)GetPropertyValue( DFF_Prop_geoBottom, 21600 ) ) - aViewBox.Y; 1688 aProp.Name = sViewBox; 1689 aProp.Value <<= aViewBox; 1690 aPropVec.push_back( aProp ); 1691 } 1692 ///////////////////// 1693 // TextRotateAngle // 1694 ///////////////////// 1695 if ( IsProperty( DFF_Prop_txflTextFlow ) || IsProperty( DFF_Prop_cdirFont ) ) 1696 { 1697 sal_Int32 nTextRotateAngle = 0; 1698 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF ); 1699 /* sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); */ 1700 1701 if ( eTextFlow == mso_txflBtoT ) // Bottom to Top non-@, unten -> oben 1702 nTextRotateAngle += 90; 1703 switch( GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ) ) // SJ: mso_cdir90 and mso_cdir270 will be simulated by 1704 { // activating vertical writing for the text objects 1705 case mso_cdir90 : 1706 { 1707 if ( eTextFlow == mso_txflTtoBA ) 1708 nTextRotateAngle -= 180; 1709 } 1710 break; 1711 case mso_cdir180: nTextRotateAngle -= 180; break; 1712 case mso_cdir270: 1713 { 1714 if ( eTextFlow != mso_txflTtoBA ) 1715 nTextRotateAngle -= 180; 1716 } 1717 break; 1718 default: break; 1719 } 1720 if ( nTextRotateAngle ) 1721 { 1722 double fTextRotateAngle = nTextRotateAngle; 1723 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) ); 1724 aProp.Name = sTextRotateAngle; 1725 aProp.Value <<= fTextRotateAngle; 1726 aPropVec.push_back( aProp ); 1727 } 1728 } 1729 ////////////////////////////////////////// 1730 // "Extrusion" PropertySequence element // 1731 ////////////////////////////////////////// 1732 sal_Bool bExtrusionOn = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 ) != 0; 1733 if ( bExtrusionOn ) 1734 { 1735 PropVec aExtrusionPropVec; 1736 1737 // "Extrusion" 1738 const rtl::OUString sExtrusionOn( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) ); 1739 aProp.Name = sExtrusionOn; 1740 aProp.Value <<= bExtrusionOn; 1741 aExtrusionPropVec.push_back( aProp ); 1742 1743 // "Brightness" 1744 if ( IsProperty( DFF_Prop_c3DAmbientIntensity ) ) 1745 { 1746 const rtl::OUString sExtrusionBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) ); 1747 double fBrightness = (sal_Int32)GetPropertyValue( DFF_Prop_c3DAmbientIntensity ); 1748 fBrightness /= 655.36; 1749 aProp.Name = sExtrusionBrightness; 1750 aProp.Value <<= fBrightness; 1751 aExtrusionPropVec.push_back( aProp ); 1752 } 1753 // "Depth" in 1/100mm 1754 if ( IsProperty( DFF_Prop_c3DExtrudeBackward ) || IsProperty( DFF_Prop_c3DExtrudeForward ) ) 1755 { 1756 const rtl::OUString sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) ); 1757 double fBackDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeBackward, 1270 * 360 )) / 360.0; 1758 double fForeDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeForward ), 0 ) / 360.0; 1759 double fDepth = fBackDepth + fForeDepth; 1760 double fFraction = fDepth != 0.0 ? fForeDepth / fDepth : 0; 1761 EnhancedCustomShapeParameterPair aDepthParaPair; 1762 aDepthParaPair.First.Value <<= fDepth; 1763 aDepthParaPair.First.Type = EnhancedCustomShapeParameterType::NORMAL; 1764 aDepthParaPair.Second.Value <<= fFraction; 1765 aDepthParaPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL; 1766 aProp.Name = sDepth; 1767 aProp.Value <<= aDepthParaPair; 1768 aExtrusionPropVec.push_back( aProp ); 1769 } 1770 // "Diffusion" 1771 if ( IsProperty( DFF_Prop_c3DDiffuseAmt ) ) 1772 { 1773 const rtl::OUString sExtrusionDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) ); 1774 double fDiffusion = (sal_Int32)GetPropertyValue( DFF_Prop_c3DDiffuseAmt ); 1775 fDiffusion /= 655.36; 1776 aProp.Name = sExtrusionDiffusion; 1777 aProp.Value <<= fDiffusion; 1778 aExtrusionPropVec.push_back( aProp ); 1779 } 1780 // "NumberOfLineSegments" 1781 if ( IsProperty( DFF_Prop_c3DTolerance ) ) 1782 { 1783 const rtl::OUString sExtrusionNumberOfLineSegments( RTL_CONSTASCII_USTRINGPARAM ( "NumberOfLineSegments" ) ); 1784 aProp.Name = sExtrusionNumberOfLineSegments; 1785 aProp.Value <<= (sal_Int32)GetPropertyValue( DFF_Prop_c3DTolerance ); 1786 aExtrusionPropVec.push_back( aProp ); 1787 } 1788 // "LightFace" 1789 const rtl::OUString sExtrusionLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) ); 1790 sal_Bool bExtrusionLightFace = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 1 ) != 0; 1791 aProp.Name = sExtrusionLightFace; 1792 aProp.Value <<= bExtrusionLightFace; 1793 aExtrusionPropVec.push_back( aProp ); 1794 // "FirstLightHarsh" 1795 const rtl::OUString sExtrusionFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) ); 1796 sal_Bool bExtrusionFirstLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 2 ) != 0; 1797 aProp.Name = sExtrusionFirstLightHarsh; 1798 aProp.Value <<= bExtrusionFirstLightHarsh; 1799 aExtrusionPropVec.push_back( aProp ); 1800 // "SecondLightHarsh" 1801 const rtl::OUString sExtrusionSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) ); 1802 sal_Bool bExtrusionSecondLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 1 ) != 0; 1803 aProp.Name = sExtrusionSecondLightHarsh; 1804 aProp.Value <<= bExtrusionSecondLightHarsh; 1805 aExtrusionPropVec.push_back( aProp ); 1806 // "FirstLightLevel" 1807 if ( IsProperty( DFF_Prop_c3DKeyIntensity ) ) 1808 { 1809 const rtl::OUString sExtrusionFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) ); 1810 double fFirstLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyIntensity ); 1811 fFirstLightLevel /= 655.36; 1812 aProp.Name = sExtrusionFirstLightLevel; 1813 aProp.Value <<= fFirstLightLevel; 1814 aExtrusionPropVec.push_back( aProp ); 1815 } 1816 // "SecondLightLevel" 1817 if ( IsProperty( DFF_Prop_c3DFillIntensity ) ) 1818 { 1819 const rtl::OUString sExtrusionSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) ); 1820 double fSecondLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DFillIntensity ); 1821 fSecondLightLevel /= 655.36; 1822 aProp.Name = sExtrusionSecondLightLevel; 1823 aProp.Value <<= fSecondLightLevel; 1824 aExtrusionPropVec.push_back( aProp ); 1825 } 1826 // "FirtstLightDirection" 1827 if ( IsProperty( DFF_Prop_c3DKeyX ) || IsProperty( DFF_Prop_c3DKeyY ) || IsProperty( DFF_Prop_c3DKeyZ ) ) 1828 { 1829 double fLightX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyX, 50000 )); 1830 double fLightY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyY, 0 )); 1831 double fLightZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyZ, 10000 )); 1832 ::com::sun::star::drawing::Direction3D aExtrusionFirstLightDirection( fLightX, fLightY, fLightZ ); 1833 const rtl::OUString sExtrusionFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) ); 1834 aProp.Name = sExtrusionFirstLightDirection; 1835 aProp.Value <<= aExtrusionFirstLightDirection; 1836 aExtrusionPropVec.push_back( aProp ); 1837 } 1838 // "SecondLightDirection" 1839 if ( IsProperty( DFF_Prop_c3DFillX ) || IsProperty( DFF_Prop_c3DFillY ) || IsProperty( DFF_Prop_c3DFillZ ) ) 1840 { 1841 double fLight2X = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillX, (sal_uInt32)-50000 )); 1842 double fLight2Y = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillY, 0 )); 1843 double fLight2Z = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillZ, 10000 )); 1844 ::com::sun::star::drawing::Direction3D aExtrusionSecondLightDirection( fLight2X, fLight2Y, fLight2Z ); 1845 const rtl::OUString sExtrusionSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) ); 1846 aProp.Name = sExtrusionSecondLightDirection; 1847 aProp.Value <<= aExtrusionSecondLightDirection; 1848 aExtrusionPropVec.push_back( aProp ); 1849 } 1850 1851 /* LockRotationCenter, OrientationAngle and Orientation needs to be converted to use the properties AngleX, AngleY and RotationAngle instead. 1852 // "LockRotationCenter" 1853 const rtl::OUString sExtrusionLockRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "LockRotationCenter" ) ); 1854 sal_Bool bExtrusionLockRotationCenter = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 16 ) != 0; 1855 aProp.Name = sExtrusionLockRotationCenter; 1856 aProp.Value <<= bExtrusionLockRotationCenter; 1857 aExtrusionPropVec.push_back( aProp ); 1858 1859 // "Orientation" 1860 if ( IsProperty( DFF_Prop_c3DRotationAxisX ) || IsProperty( DFF_Prop_c3DRotationAxisY ) || IsProperty( DFF_Prop_c3DRotationAxisZ ) ) 1861 { 1862 double fRotX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 )); 1863 double fRotY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 )); 1864 double fRotZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 )); 1865 ::com::sun::star::drawing::Direction3D aExtrusionDirection( fRotX, fRotY, fRotZ ); 1866 const rtl::OUString sExtrusionDirection( RTL_CONSTASCII_USTRINGPARAM ( "Orientation" ) ); 1867 aProp.Name = sExtrusionDirection; 1868 aProp.Value <<= aExtrusionDirection; 1869 aExtrusionPropVec.push_back( aProp ); 1870 } 1871 // "OrientationAngle" in Grad 1872 if ( IsProperty( DFF_Prop_c3DRotationAngle ) ) 1873 { 1874 const rtl::OUString sExtrusionOrientationAngle( RTL_CONSTASCII_USTRINGPARAM ( "OrientationAngle" ) ); 1875 double fOrientationAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAngle )) / 65536.0; 1876 aProp.Name = sExtrusionOrientationAngle; 1877 aProp.Value <<= fOrientationAngle; 1878 aExtrusionPropVec.push_back( aProp ); 1879 } 1880 */ 1881 1882 // "Metal" 1883 const rtl::OUString sExtrusionMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) ); 1884 sal_Bool bExtrusionMetal = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 4 ) != 0; 1885 aProp.Name = sExtrusionMetal; 1886 aProp.Value <<= bExtrusionMetal; 1887 aExtrusionPropVec.push_back( aProp ); 1888 // if ( IsProperty( DFF_Prop_c3DExtrudePlane ) ) 1889 // { 1890 // UPS 1891 // } 1892 // "ShadeMode" 1893 if ( IsProperty( DFF_Prop_c3DRenderMode ) ) 1894 { 1895 const rtl::OUString sExtrusionShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) ); 1896 sal_uInt32 nExtrusionRenderMode = GetPropertyValue( DFF_Prop_c3DRenderMode ); 1897 com::sun::star::drawing::ShadeMode eExtrusionShadeMode( com::sun::star::drawing::ShadeMode_FLAT ); 1898 if ( nExtrusionRenderMode == mso_Wireframe ) 1899 eExtrusionShadeMode = com::sun::star::drawing::ShadeMode_DRAFT; 1900 1901 aProp.Name = sExtrusionShadeMode; 1902 aProp.Value <<= eExtrusionShadeMode; 1903 aExtrusionPropVec.push_back( aProp ); 1904 } 1905 // "RotateAngle" in Grad 1906 if ( IsProperty( DFF_Prop_c3DXRotationAngle ) || IsProperty( DFF_Prop_c3DYRotationAngle ) ) 1907 { 1908 const rtl::OUString sExtrusionAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) ); 1909 double fAngleX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXRotationAngle, 0 )) / 65536.0; 1910 double fAngleY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYRotationAngle, 0 )) / 65536.0; 1911 EnhancedCustomShapeParameterPair aRotateAnglePair; 1912 aRotateAnglePair.First.Value <<= fAngleX; 1913 aRotateAnglePair.First.Type = EnhancedCustomShapeParameterType::NORMAL; 1914 aRotateAnglePair.Second.Value <<= fAngleY; 1915 aRotateAnglePair.Second.Type = EnhancedCustomShapeParameterType::NORMAL; 1916 aProp.Name = sExtrusionAngle; 1917 aProp.Value <<= aRotateAnglePair; 1918 aExtrusionPropVec.push_back( aProp ); 1919 } 1920 1921 // "AutoRotationCenter" 1922 if ( ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 8 ) == 0 ) 1923 { 1924 // "RotationCenter" 1925 if ( IsProperty( DFF_Prop_c3DRotationCenterX ) || IsProperty( DFF_Prop_c3DRotationCenterY ) || IsProperty( DFF_Prop_c3DRotationCenterZ ) ) 1926 { 1927 ::com::sun::star::drawing::Direction3D aRotationCenter( 1928 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 )) / 360.0, 1929 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 )) / 360.0, 1930 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterZ, 0 )) / 360.0 ); 1931 1932 const rtl::OUString sExtrusionRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) ); 1933 aProp.Name = sExtrusionRotationCenter; 1934 aProp.Value <<= aRotationCenter; 1935 aExtrusionPropVec.push_back( aProp ); 1936 } 1937 } 1938 // "Shininess" 1939 if ( IsProperty( DFF_Prop_c3DShininess ) ) 1940 { 1941 const rtl::OUString sExtrusionShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) ); 1942 double fShininess = (sal_Int32)GetPropertyValue( DFF_Prop_c3DShininess ); 1943 fShininess /= 655.36; 1944 aProp.Name = sExtrusionShininess; 1945 aProp.Value <<= fShininess; 1946 aExtrusionPropVec.push_back( aProp ); 1947 } 1948 // "Skew" 1949 if ( IsProperty( DFF_Prop_c3DSkewAmount ) || IsProperty( DFF_Prop_c3DSkewAngle ) ) 1950 { 1951 const rtl::OUString sExtrusionSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) ); 1952 double fSkewAmount = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAmount, 50 ); 1953 double fSkewAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAngle, sal::static_int_cast< sal_uInt32 >(-135 * 65536) )) / 65536.0; 1954 1955 EnhancedCustomShapeParameterPair aSkewPair; 1956 aSkewPair.First.Value <<= fSkewAmount; 1957 aSkewPair.First.Type = EnhancedCustomShapeParameterType::NORMAL; 1958 aSkewPair.Second.Value <<= fSkewAngle; 1959 aSkewPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL; 1960 aProp.Name = sExtrusionSkew; 1961 aProp.Value <<= aSkewPair; 1962 aExtrusionPropVec.push_back( aProp ); 1963 } 1964 // "Specularity" 1965 if ( IsProperty( DFF_Prop_c3DSpecularAmt ) ) 1966 { 1967 const rtl::OUString sExtrusionSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) ); 1968 double fSpecularity = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSpecularAmt ); 1969 fSpecularity /= 1333; 1970 aProp.Name = sExtrusionSpecularity; 1971 aProp.Value <<= fSpecularity; 1972 aExtrusionPropVec.push_back( aProp ); 1973 } 1974 // "ProjectionMode" 1975 const rtl::OUString sExtrusionProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) ); 1976 ProjectionMode eProjectionMode = GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 4 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE; 1977 aProp.Name = sExtrusionProjectionMode; 1978 aProp.Value <<= eProjectionMode; 1979 aExtrusionPropVec.push_back( aProp ); 1980 1981 // "ViewPoint" in 1/100mm 1982 if ( IsProperty( DFF_Prop_c3DXViewpoint ) || IsProperty( DFF_Prop_c3DYViewpoint ) || IsProperty( DFF_Prop_c3DZViewpoint ) ) 1983 { 1984 double fViewX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXViewpoint, 1250000 )) / 360.0; 1985 double fViewY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYViewpoint, (sal_uInt32)-1250000 ))/ 360.0; 1986 double fViewZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DZViewpoint, 9000000 )) / 360.0; 1987 ::com::sun::star::drawing::Position3D aExtrusionViewPoint( fViewX, fViewY, fViewZ ); 1988 const rtl::OUString sExtrusionViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) ); 1989 aProp.Name = sExtrusionViewPoint; 1990 aProp.Value <<= aExtrusionViewPoint; 1991 aExtrusionPropVec.push_back( aProp ); 1992 } 1993 // "Origin" 1994 if ( IsProperty( DFF_Prop_c3DOriginX ) || IsProperty( DFF_Prop_c3DOriginY ) ) 1995 { 1996 const rtl::OUString sExtrusionOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) ); 1997 double fOriginX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginX, 0 )); 1998 double fOriginY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginY, 0 )); 1999 fOriginX /= 65536; 2000 fOriginY /= 65536; 2001 EnhancedCustomShapeParameterPair aOriginPair; 2002 aOriginPair.First.Value <<= fOriginX; 2003 aOriginPair.First.Type = EnhancedCustomShapeParameterType::NORMAL; 2004 aOriginPair.Second.Value <<= fOriginY; 2005 aOriginPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL; 2006 aProp.Name = sExtrusionOrigin; 2007 aProp.Value <<= aOriginPair; 2008 aExtrusionPropVec.push_back( aProp ); 2009 } 2010 // "ExtrusionColor" 2011 const rtl::OUString sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) ); 2012 sal_Bool bExtrusionColor = IsProperty( DFF_Prop_c3DExtrusionColor ); // ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 2 ) != 0; 2013 aProp.Name = sExtrusionColor; 2014 aProp.Value <<= bExtrusionColor; 2015 aExtrusionPropVec.push_back( aProp ); 2016 if ( IsProperty( DFF_Prop_c3DExtrusionColor ) ) 2017 rSet.Put( XSecondaryFillColorItem( String(), rManager.MSO_CLR_ToColor( 2018 GetPropertyValue( DFF_Prop_c3DExtrusionColor ), DFF_Prop_c3DExtrusionColor ) ) ); 2019 // pushing the whole Extrusion element 2020 const rtl::OUString sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) ); 2021 PropSeq aExtrusionPropSeq( aExtrusionPropVec.size() ); 2022 aIter = aExtrusionPropVec.begin(); 2023 aEnd = aExtrusionPropVec.end(); 2024 beans::PropertyValue* pExtrusionValues = aExtrusionPropSeq.getArray(); 2025 while ( aIter != aEnd ) 2026 *pExtrusionValues++ = *aIter++; 2027 aProp.Name = sExtrusion; 2028 aProp.Value <<= aExtrusionPropSeq; 2029 aPropVec.push_back( aProp ); 2030 } 2031 2032 ///////////////////////////////////////// 2033 // "Equations" PropertySequence element // 2034 ///////////////////////////////////////// 2035 if ( IsProperty( DFF_Prop_pFormulas ) ) 2036 { 2037 sal_uInt16 i; 2038 sal_uInt16 nNumElem = 0; 2039 sal_uInt16 nNumElemMem = 0; 2040 sal_uInt16 nElemSize = 8; 2041 2042 if ( SeekToContent( DFF_Prop_pFormulas, rIn ) ) 2043 rIn >> nNumElem >> nNumElemMem >> nElemSize; 2044 2045 sal_Int16 nP1, nP2, nP3; 2046 sal_uInt16 nFlags; 2047 2048 uno::Sequence< rtl::OUString > aEquations( nNumElem ); 2049 for ( i = 0; i < nNumElem; i++ ) 2050 { 2051 rIn >> nFlags >> nP1 >> nP2 >> nP3; 2052 aEquations[ i ] = EnhancedCustomShape2d::GetEquation( nFlags, nP1, nP2, nP3 ); 2053 } 2054 // pushing the whole Equations element 2055 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) ); 2056 aProp.Name = sEquations; 2057 aProp.Value <<= aEquations; 2058 aPropVec.push_back( aProp ); 2059 } 2060 2061 //////////////////////////////////////// 2062 // "Handles" PropertySequence element // 2063 //////////////////////////////////////// 2064 if ( IsProperty( DFF_Prop_Handles ) ) 2065 { 2066 sal_uInt16 i; 2067 sal_uInt16 nNumElem = 0; 2068 sal_uInt16 nNumElemMem = 0; 2069 sal_uInt16 nElemSize = 36; 2070 2071 if ( SeekToContent( DFF_Prop_Handles, rIn ) ) 2072 rIn >> nNumElem >> nNumElemMem >> nElemSize; 2073 if ( nElemSize == 36 ) 2074 { 2075 uno::Sequence< beans::PropertyValues > aHandles( nNumElem ); 2076 for ( i = 0; i < nNumElem; i++ ) 2077 { 2078 PropVec aHandlePropVec; 2079 sal_uInt32 nFlags; 2080 sal_Int32 nPositionX, nPositionY, nCenterX, nCenterY, nRangeXMin, nRangeXMax, nRangeYMin, nRangeYMax; 2081 rIn >> nFlags 2082 >> nPositionX 2083 >> nPositionY 2084 >> nCenterX 2085 >> nCenterY 2086 >> nRangeXMin 2087 >> nRangeXMax 2088 >> nRangeYMin 2089 >> nRangeYMax; 2090 2091 if ( nPositionX == 2 ) // replacing center position with absolute value 2092 nPositionX = nCoordWidth / 2; 2093 if ( nPositionY == 2 ) 2094 nPositionY = nCoordHeight / 2; 2095 EnhancedCustomShapeParameterPair aPosition; 2096 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, nPositionX, sal_True, sal_True ); 2097 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, nPositionY, sal_True, sal_False ); 2098 const rtl::OUString sHandlePosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) ); 2099 aProp.Name = sHandlePosition; 2100 aProp.Value <<= aPosition; 2101 aHandlePropVec.push_back( aProp ); 2102 2103 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X ) 2104 { 2105 sal_Bool bMirroredX = sal_True; 2106 const rtl::OUString sHandleMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) ); 2107 aProp.Name = sHandleMirroredX; 2108 aProp.Value <<= bMirroredX; 2109 aHandlePropVec.push_back( aProp ); 2110 } 2111 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y ) 2112 { 2113 sal_Bool bMirroredY = sal_True; 2114 const rtl::OUString sHandleMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) ); 2115 aProp.Name = sHandleMirroredY; 2116 aProp.Value <<= bMirroredY; 2117 aHandlePropVec.push_back( aProp ); 2118 } 2119 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED ) 2120 { 2121 sal_Bool bSwitched = sal_True; 2122 const rtl::OUString sHandleSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) ); 2123 aProp.Name = sHandleSwitched; 2124 aProp.Value <<= bSwitched; 2125 aHandlePropVec.push_back( aProp ); 2126 } 2127 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR ) 2128 { 2129 if ( nCenterX == 2 ) 2130 nCenterX = nCoordWidth / 2; 2131 if ( nCenterY == 2 ) 2132 nCenterY = nCoordHeight / 2; 2133 if ( ( nPositionY >= 0x256 ) || ( nPositionY <= 0x107 ) ) // position y 2134 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i ); 2135 EnhancedCustomShapeParameterPair aPolar; 2136 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True ); 2137 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False ); 2138 const rtl::OUString sHandlePolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) ); 2139 aProp.Name = sHandlePolar; 2140 aProp.Value <<= aPolar; 2141 aHandlePropVec.push_back( aProp ); 2142 } 2143 if ( nFlags & MSDFF_HANDLE_FLAGS_MAP ) 2144 { 2145 if ( nCenterX == 2 ) 2146 nCenterX = nCoordWidth / 2; 2147 if ( nCenterY == 2 ) 2148 nCenterY = nCoordHeight / 2; 2149 EnhancedCustomShapeParameterPair aMap; 2150 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True ); 2151 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False ); 2152 const rtl::OUString sHandleMap( RTL_CONSTASCII_USTRINGPARAM ( "Map" ) ); 2153 aProp.Name = sHandleMap; 2154 aProp.Value <<= aMap; 2155 aHandlePropVec.push_back( aProp ); 2156 } 2157 if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE ) 2158 { 2159 if ( (sal_uInt32)nRangeXMin != 0x80000000 ) 2160 { 2161 if ( nRangeXMin == 2 ) 2162 nRangeXMin = nCoordWidth / 2; 2163 EnhancedCustomShapeParameter aRangeXMinimum; 2164 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, nRangeXMin, 2165 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True ); 2166 const rtl::OUString sHandleRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) ); 2167 aProp.Name = sHandleRangeXMinimum; 2168 aProp.Value <<= aRangeXMinimum; 2169 aHandlePropVec.push_back( aProp ); 2170 } 2171 if ( (sal_uInt32)nRangeXMax != 0x7fffffff ) 2172 { 2173 if ( nRangeXMax == 2 ) 2174 nRangeXMax = nCoordWidth / 2; 2175 EnhancedCustomShapeParameter aRangeXMaximum; 2176 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, nRangeXMax, 2177 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False ); 2178 const rtl::OUString sHandleRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) ); 2179 aProp.Name = sHandleRangeXMaximum; 2180 aProp.Value <<= aRangeXMaximum; 2181 aHandlePropVec.push_back( aProp ); 2182 } 2183 if ( (sal_uInt32)nRangeYMin != 0x80000000 ) 2184 { 2185 if ( nRangeYMin == 2 ) 2186 nRangeYMin = nCoordHeight / 2; 2187 EnhancedCustomShapeParameter aRangeYMinimum; 2188 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, nRangeYMin, 2189 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True ); 2190 const rtl::OUString sHandleRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) ); 2191 aProp.Name = sHandleRangeYMinimum; 2192 aProp.Value <<= aRangeYMinimum; 2193 aHandlePropVec.push_back( aProp ); 2194 } 2195 if ( (sal_uInt32)nRangeYMax != 0x7fffffff ) 2196 { 2197 if ( nRangeYMax == 2 ) 2198 nRangeYMax = nCoordHeight / 2; 2199 EnhancedCustomShapeParameter aRangeYMaximum; 2200 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, nRangeYMax, 2201 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False ); 2202 const rtl::OUString sHandleRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) ); 2203 aProp.Name = sHandleRangeYMaximum; 2204 aProp.Value <<= aRangeYMaximum; 2205 aHandlePropVec.push_back( aProp ); 2206 } 2207 } 2208 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE ) 2209 { 2210 if ( (sal_uInt32)nRangeXMin != 0x7fffffff ) 2211 { 2212 if ( nRangeXMin == 2 ) 2213 nRangeXMin = nCoordWidth / 2; 2214 EnhancedCustomShapeParameter aRadiusRangeMinimum; 2215 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, nRangeXMin, 2216 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True ); 2217 const rtl::OUString sHandleRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) ); 2218 aProp.Name = sHandleRadiusRangeMinimum; 2219 aProp.Value <<= aRadiusRangeMinimum; 2220 aHandlePropVec.push_back( aProp ); 2221 } 2222 if ( (sal_uInt32)nRangeXMax != 0x80000000 ) 2223 { 2224 if ( nRangeXMax == 2 ) 2225 nRangeXMax = nCoordWidth / 2; 2226 EnhancedCustomShapeParameter aRadiusRangeMaximum; 2227 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, nRangeXMax, 2228 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False ); 2229 const rtl::OUString sHandleRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) ); 2230 aProp.Name = sHandleRadiusRangeMaximum; 2231 aProp.Value <<= aRadiusRangeMaximum; 2232 aHandlePropVec.push_back( aProp ); 2233 } 2234 } 2235 if ( aHandlePropVec.size() ) 2236 { 2237 PropSeq aHandlePropSeq( aHandlePropVec.size() ); 2238 aIter = aHandlePropVec.begin(); 2239 aEnd = aHandlePropVec.end(); 2240 beans::PropertyValue* pHandleValues = aHandlePropSeq.getArray(); 2241 while ( aIter != aEnd ) 2242 *pHandleValues++ = *aIter++; 2243 aHandles[ i ] = aHandlePropSeq; 2244 } 2245 } 2246 // pushing the whole Handles element 2247 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) ); 2248 aProp.Name = sHandles; 2249 aProp.Value <<= aHandles; 2250 aPropVec.push_back( aProp ); 2251 } 2252 } 2253 else 2254 { 2255 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( rObjData.eShapeType ); 2256 if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles ) 2257 { 2258 sal_Int32 i, nCnt = pDefCustomShape->nHandles; 2259 const SvxMSDffHandle* pData = pDefCustomShape->pHandles; 2260 for ( i = 0; i < nCnt; i++, pData++ ) 2261 { 2262 if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR ) 2263 { 2264 if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) ) 2265 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i ); 2266 } 2267 } 2268 } 2269 } 2270 ///////////////////////////////////// 2271 // "Path" PropertySequence element // 2272 ///////////////////////////////////// 2273 { 2274 PropVec aPathPropVec; 2275 2276 // "Path/ExtrusionAllowed" 2277 if ( IsHardAttribute( DFF_Prop_f3DOK ) ) 2278 { 2279 const rtl::OUString sExtrusionAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ExtrusionAllowed" ) ); 2280 sal_Bool bExtrusionAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 16 ) != 0; 2281 aProp.Name = sExtrusionAllowed; 2282 aProp.Value <<= bExtrusionAllowed; 2283 aPathPropVec.push_back( aProp ); 2284 } 2285 // "Path/ConcentricGradientFillAllowed" 2286 if ( IsHardAttribute( DFF_Prop_fFillShadeShapeOK ) ) 2287 { 2288 const rtl::OUString sConcentricGradientFillAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ConcentricGradientFillAllowed" ) ); 2289 sal_Bool bConcentricGradientFillAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 2 ) != 0; 2290 aProp.Name = sConcentricGradientFillAllowed; 2291 aProp.Value <<= bConcentricGradientFillAllowed; 2292 aPathPropVec.push_back( aProp ); 2293 } 2294 // "Path/TextPathAllowed" 2295 if ( IsHardAttribute( DFF_Prop_fGtextOK ) || ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) ) 2296 { 2297 const rtl::OUString sTextPathAllowed( RTL_CONSTASCII_USTRINGPARAM ( "TextPathAllowed" ) ); 2298 sal_Bool bTextPathAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 4 ) != 0; 2299 aProp.Name = sTextPathAllowed; 2300 aProp.Value <<= bTextPathAllowed; 2301 aPathPropVec.push_back( aProp ); 2302 } 2303 // Path/Coordinates 2304 if ( IsProperty( DFF_Prop_pVertices ) ) 2305 { 2306 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates; 2307 2308 sal_uInt16 i; 2309 sal_uInt16 nNumElemVert = 0; 2310 sal_uInt16 nNumElemMemVert = 0; 2311 sal_uInt16 nElemSizeVert = 8; 2312 2313 if ( SeekToContent( DFF_Prop_pVertices, rIn ) ) 2314 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert; 2315 if ( nNumElemVert ) 2316 { 2317 sal_Int32 nX, nY; 2318 sal_Int16 nTmpA, nTmpB; 2319 aCoordinates.realloc( nNumElemVert ); 2320 for ( i = 0; i < nNumElemVert; i++ ) 2321 { 2322 if ( nElemSizeVert == 8 ) 2323 { 2324 rIn >> nX 2325 >> nY; 2326 } 2327 else 2328 { 2329 rIn >> nTmpA 2330 >> nTmpB; 2331 2332 nX = nTmpA; 2333 nY = nTmpB; 2334 } 2335 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].First, nX ); 2336 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].Second, nY ); 2337 } 2338 } 2339 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) ); 2340 aProp.Name = sCoordinates; 2341 aProp.Value <<= aCoordinates; 2342 aPathPropVec.push_back( aProp ); 2343 } 2344 // Path/Segments 2345 if ( IsProperty( DFF_Prop_pSegmentInfo ) ) 2346 { 2347 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments; 2348 2349 sal_uInt16 i, nTmp; 2350 sal_uInt16 nNumElemSeg = 0; 2351 sal_uInt16 nNumElemMemSeg = 0; 2352 sal_uInt16 nElemSizeSeg = 2; 2353 2354 if ( SeekToContent( DFF_Prop_pSegmentInfo, rIn ) ) 2355 rIn >> nNumElemSeg >> nNumElemMemSeg >> nElemSizeSeg; 2356 if ( nNumElemSeg ) 2357 { 2358 sal_Int16 nCommand; 2359 sal_Int16 nCnt; 2360 aSegments.realloc( nNumElemSeg ); 2361 for ( i = 0; i < nNumElemSeg; i++ ) 2362 { 2363 rIn >> nTmp; 2364 nCommand = EnhancedCustomShapeSegmentCommand::UNKNOWN; 2365 nCnt = (sal_Int16)( nTmp & 0xfff ); 2366 switch( nTmp >> 12 ) 2367 { 2368 case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break; 2369 case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break; // seems to the relative lineto 2370 case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break; 2371 case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break; 2372 case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break; // seems to be the relative curveto 2373 case 0x8: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break; 2374 case 0x6: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break; 2375 case 0xa: 2376 case 0xb: 2377 { 2378 switch ( ( nTmp >> 8 ) & 0xf ) 2379 { 2380 case 0x0: 2381 { 2382 nCommand = EnhancedCustomShapeSegmentCommand::LINETO; 2383 if ( !nCnt ) 2384 nCnt = 1; 2385 } 2386 break; 2387 case 0x1: 2388 { 2389 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO; 2390 nCnt = ( nTmp & 0xff ) / 3; 2391 } 2392 break; 2393 case 0x2: 2394 { 2395 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE; 2396 nCnt = ( nTmp & 0xff ) / 3; 2397 } 2398 break; 2399 case 0x3: 2400 { 2401 nCommand = EnhancedCustomShapeSegmentCommand::ARCTO; 2402 nCnt = ( nTmp & 0xff ) >> 2; 2403 }; 2404 break; 2405 case 0x4: 2406 { 2407 nCommand = EnhancedCustomShapeSegmentCommand::ARC; 2408 nCnt = ( nTmp & 0xff ) >> 2; 2409 } 2410 break; 2411 case 0x5: 2412 { 2413 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO; 2414 nCnt = ( nTmp & 0xff ) >> 2; 2415 } 2416 break; 2417 case 0x6: 2418 { 2419 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC; 2420 nCnt = ( nTmp & 0xff ) >> 2; 2421 } 2422 break; 2423 case 0x7: 2424 { 2425 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX; 2426 nCnt = nTmp & 0xff; 2427 } 2428 break; 2429 case 0x8: 2430 { 2431 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY; 2432 nCnt = nTmp & 0xff; 2433 } 2434 break; 2435 case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break; 2436 case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break; 2437 } 2438 } 2439 break; 2440 } 2441 // if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss 2442 if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN ) 2443 nCnt = (sal_Int16)nTmp; 2444 aSegments[ i ].Command = nCommand; 2445 aSegments[ i ].Count = nCnt; 2446 } 2447 } 2448 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) ); 2449 aProp.Name = sSegments; 2450 aProp.Value <<= aSegments; 2451 aPathPropVec.push_back( aProp ); 2452 } 2453 // Path/StretchX 2454 if ( IsProperty( DFF_Prop_stretchPointX ) ) 2455 { 2456 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) ); 2457 sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 ); 2458 aProp.Name = sStretchX; 2459 aProp.Value <<= nStretchX; 2460 aPathPropVec.push_back( aProp ); 2461 } 2462 // Path/StretchX 2463 if ( IsProperty( DFF_Prop_stretchPointY ) ) 2464 { 2465 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) ); 2466 sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 ); 2467 aProp.Name = sStretchY; 2468 aProp.Value <<= nStretchY; 2469 aPathPropVec.push_back( aProp ); 2470 } 2471 // Path/TextFrames 2472 if ( IsProperty( DFF_Prop_textRectangles ) ) 2473 { 2474 sal_uInt16 i; 2475 sal_uInt16 nNumElem = 0; 2476 sal_uInt16 nNumElemMem = 0; 2477 sal_uInt16 nElemSize = 16; 2478 2479 if ( SeekToContent( DFF_Prop_textRectangles, rIn ) ) 2480 rIn >> nNumElem >> nNumElemMem >> nElemSize; 2481 if ( nElemSize == 16 ) 2482 { 2483 sal_Int32 nLeft, nTop, nRight, nBottom; 2484 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem ); 2485 for ( i = 0; i < nNumElem; i++ ) 2486 { 2487 rIn >> nLeft 2488 >> nTop 2489 >> nRight 2490 >> nBottom; 2491 2492 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First, nLeft ); 2493 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop ); 2494 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First, nRight ); 2495 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom); 2496 } 2497 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) ); 2498 aProp.Name = sTextFrames; 2499 aProp.Value <<= aTextFrames; 2500 aPathPropVec.push_back( aProp ); 2501 } 2502 } 2503 //Path/GluePoints 2504 if ( IsProperty( DFF_Prop_connectorPoints ) ) 2505 { 2506 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints; 2507 2508 sal_uInt16 i; 2509 sal_uInt16 nNumElemVert = 0; 2510 sal_uInt16 nNumElemMemVert = 0; 2511 sal_uInt16 nElemSizeVert = 8; 2512 2513 if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) ) 2514 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert; 2515 2516 sal_Int32 nX, nY; 2517 sal_Int16 nTmpA, nTmpB; 2518 aGluePoints.realloc( nNumElemVert ); 2519 for ( i = 0; i < nNumElemVert; i++ ) 2520 { 2521 if ( nElemSizeVert == 8 ) 2522 { 2523 rIn >> nX 2524 >> nY; 2525 } 2526 else 2527 { 2528 rIn >> nTmpA 2529 >> nTmpB; 2530 2531 nX = nTmpA; 2532 nY = nTmpB; 2533 } 2534 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First, nX ); 2535 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY ); 2536 } 2537 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) ); 2538 aProp.Name = sGluePoints; 2539 aProp.Value <<= aGluePoints; 2540 aPathPropVec.push_back( aProp ); 2541 } 2542 if ( IsProperty( DFF_Prop_connectorType ) ) 2543 { 2544 sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType ); 2545 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) ); 2546 aProp.Name = sGluePointType; 2547 aProp.Value <<= nGluePointType; 2548 aPathPropVec.push_back( aProp ); 2549 } 2550 // pushing the whole Path element 2551 if ( aPathPropVec.size() ) 2552 { 2553 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); 2554 PropSeq aPathPropSeq( aPathPropVec.size() ); 2555 aIter = aPathPropVec.begin(); 2556 aEnd = aPathPropVec.end(); 2557 beans::PropertyValue* pPathValues = aPathPropSeq.getArray(); 2558 while ( aIter != aEnd ) 2559 *pPathValues++ = *aIter++; 2560 aProp.Name = sPath; 2561 aProp.Value <<= aPathPropSeq; 2562 aPropVec.push_back( aProp ); 2563 } 2564 } 2565 ///////////////////////////////////////// 2566 // "TextPath" PropertySequence element // 2567 ///////////////////////////////////////// 2568 sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0; 2569 if ( bTextPathOn ) 2570 { 2571 PropVec aTextPathPropVec; 2572 2573 // TextPath 2574 const rtl::OUString sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); 2575 aProp.Name = sTextPathOn; 2576 aProp.Value <<= bTextPathOn; 2577 aTextPathPropVec.push_back( aProp ); 2578 2579 // TextPathMode 2580 const rtl::OUString sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) ); 2581 sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0; 2582 2583 sal_Bool bTextPathFitShape; 2584 if ( IsHardAttribute( DFF_Prop_gtextFStretch ) ) 2585 bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0; 2586 else 2587 { 2588 bTextPathFitShape = true; 2589 switch( rObjData.eShapeType ) 2590 { 2591 case mso_sptTextArchUpCurve : 2592 case mso_sptTextArchDownCurve : 2593 case mso_sptTextCircleCurve : 2594 case mso_sptTextButtonCurve : 2595 bTextPathFitShape = false; 2596 default : break; 2597 } 2598 } 2599 EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL ); 2600 if ( bTextPathFitShape ) 2601 eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE; 2602 else if ( bTextPathFitPath ) 2603 eTextPathMode = EnhancedCustomShapeTextPathMode_PATH; 2604 aProp.Name = sTextPathMode; 2605 aProp.Value <<= eTextPathMode; 2606 aTextPathPropVec.push_back( aProp ); 2607 2608 // ScaleX 2609 const rtl::OUString sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) ); 2610 sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0; 2611 aProp.Name = sTextPathScaleX; 2612 aProp.Value <<= bTextPathScaleX; 2613 aTextPathPropVec.push_back( aProp ); 2614 // SameLetterHeights 2615 const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) ); 2616 sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0; 2617 aProp.Name = sSameLetterHeight; 2618 aProp.Value <<= bSameLetterHeight; 2619 aTextPathPropVec.push_back( aProp ); 2620 2621 // pushing the whole TextPath element 2622 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); 2623 PropSeq aTextPathPropSeq( aTextPathPropVec.size() ); 2624 aIter = aTextPathPropVec.begin(); 2625 aEnd = aTextPathPropVec.end(); 2626 beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray(); 2627 while ( aIter != aEnd ) 2628 *pTextPathValues++ = *aIter++; 2629 aProp.Name = sTextPath; 2630 aProp.Value <<= aTextPathPropSeq; 2631 aPropVec.push_back( aProp ); 2632 } 2633 //////////////////////// 2634 // "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the 2635 //////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double 2636 2637 // checking the last used adjustment handle, so we can determine how many handles are to allocate 2638 sal_Int32 i = DFF_Prop_adjust10Value; 2639 while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) ) 2640 i--; 2641 sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1; 2642 if ( nAdjustmentValues ) 2643 { 2644 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues ); 2645 while( --nAdjustmentValues >= 0 ) 2646 { 2647 sal_Int32 nValue = 0; 2648 beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE; 2649 if ( IsProperty( i ) ) 2650 { 2651 nValue = GetPropertyValue( i ); 2652 ePropertyState = beans::PropertyState_DIRECT_VALUE; 2653 } 2654 if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) ) 2655 { 2656 double fValue = nValue; 2657 fValue /= 65536; 2658 aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue; 2659 } 2660 else 2661 aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue; 2662 aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState; 2663 i--; 2664 } 2665 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); 2666 aProp.Name = sAdjustmentValues; 2667 aProp.Value <<= aAdjustmentSeq; 2668 aPropVec.push_back( aProp ); 2669 } 2670 2671 // creating the whole property set 2672 PropSeq aSeq( aPropVec.size() ); 2673 beans::PropertyValue* pValues = aSeq.getArray(); 2674 aIter = aPropVec.begin(); 2675 aEnd = aPropVec.end(); 2676 while ( aIter != aEnd ) 2677 *pValues++ = *aIter++; 2678 rSet.Put( SdrCustomShapeGeometryItem( aSeq ) ); 2679 } 2680 2681 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const 2682 { 2683 Rectangle aEmptyRect; 2684 DffRecordHeader aHdTemp; 2685 DffObjData aDffObjTemp( aHdTemp, aEmptyRect, 0 ); 2686 ApplyAttributes( rIn, rSet, aDffObjTemp ); 2687 } 2688 2689 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const 2690 { 2691 sal_Bool bHasShadow = sal_False; 2692 if ( IsProperty( DFF_Prop_gtextSize ) ) 2693 rSet.Put( SvxFontHeightItem( rManager.ScalePt( GetPropertyValue( DFF_Prop_gtextSize ) ), 100, EE_CHAR_FONTHEIGHT ) ); 2694 sal_uInt32 nFontAttributes = GetPropertyValue( DFF_Prop_gtextFStrikethrough ); 2695 if ( nFontAttributes & 0x20 ) 2696 rSet.Put( SvxWeightItem( nFontAttributes & 0x20 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); 2697 if ( nFontAttributes & 0x10 ) 2698 rSet.Put( SvxPostureItem( nFontAttributes & 0x10 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) ); 2699 if ( nFontAttributes & 0x08 ) 2700 rSet.Put( SvxUnderlineItem( nFontAttributes & 0x08 ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) ); 2701 if ( nFontAttributes & 0x40 ) 2702 rSet.Put( SvxShadowedItem( nFontAttributes & 0x40 != 0, EE_CHAR_SHADOW ) ); 2703 // if ( nFontAttributes & 0x02 ) 2704 // rSet.Put( SvxCaseMapItem( nFontAttributes & 0x02 ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) ); 2705 if ( nFontAttributes & 0x01 ) 2706 rSet.Put( SvxCrossedOutItem( nFontAttributes & 0x01 ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) ); 2707 if ( IsProperty( DFF_Prop_fillColor ) ) 2708 rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor ) ) ); 2709 if ( IsProperty( DFF_Prop_shadowType ) ) 2710 { 2711 MSO_ShadowType eShadowType = static_cast< MSO_ShadowType >( GetPropertyValue( DFF_Prop_shadowType ) ); 2712 if( eShadowType != mso_shadowOffset ) 2713 { 2714 rSet.Put( SdrShadowXDistItem( 35 ) ); // 0,35 mm Schattendistanz 2715 rSet.Put( SdrShadowYDistItem( 35 ) ); 2716 } 2717 } 2718 if ( IsProperty( DFF_Prop_shadowColor ) ) 2719 rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_shadowColor ), DFF_Prop_shadowColor ) ) ); 2720 if ( IsProperty( DFF_Prop_shadowOpacity ) ) 2721 rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - GetPropertyValue( DFF_Prop_shadowOpacity ) ) / 655 ) ) ); 2722 if ( IsProperty( DFF_Prop_shadowOffsetX ) ) 2723 { 2724 sal_Int32 nVal = static_cast< sal_Int32 >( GetPropertyValue( DFF_Prop_shadowOffsetX ) ); 2725 rManager.ScaleEmu( nVal ); 2726 if ( nVal ) 2727 rSet.Put( SdrShadowXDistItem( nVal ) ); 2728 } 2729 if ( IsProperty( DFF_Prop_shadowOffsetY ) ) 2730 { 2731 sal_Int32 nVal = static_cast< sal_Int32 >( GetPropertyValue( DFF_Prop_shadowOffsetY ) ); 2732 rManager.ScaleEmu( nVal ); 2733 if ( nVal ) 2734 rSet.Put( SdrShadowYDistItem( nVal ) ); 2735 } 2736 if ( IsProperty( DFF_Prop_fshadowObscured ) ) 2737 { 2738 bHasShadow = ( GetPropertyValue( DFF_Prop_fshadowObscured ) & 2 ) != 0; 2739 if ( bHasShadow ) 2740 { 2741 if ( !IsProperty( DFF_Prop_shadowOffsetX ) ) 2742 rSet.Put( SdrShadowXDistItem( 35 ) ); 2743 if ( !IsProperty( DFF_Prop_shadowOffsetY ) ) 2744 rSet.Put( SdrShadowYDistItem( 35 ) ); 2745 } 2746 } 2747 if ( bHasShadow ) 2748 { 2749 // #160376# sj: activating shadow only if fill and or linestyle is used 2750 // this is required because of the latest drawing layer core changes. 2751 // Issue i104085 is related to this. 2752 sal_uInt32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash )); 2753 if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( rObjData.eShapeType )) 2754 nLineFlags &= ~0x08; 2755 sal_uInt32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest )); 2756 if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType )) 2757 nFillFlags &= ~0x10; 2758 if ( nFillFlags & 0x10 ) 2759 { 2760 MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid ); 2761 switch( eMSO_FillType ) 2762 { 2763 case mso_fillSolid : 2764 case mso_fillPattern : 2765 case mso_fillTexture : 2766 case mso_fillPicture : 2767 case mso_fillShade : 2768 case mso_fillShadeCenter : 2769 case mso_fillShadeShape : 2770 case mso_fillShadeScale : 2771 case mso_fillShadeTitle : 2772 break; 2773 // case mso_fillBackground : 2774 default: 2775 nFillFlags &=~0x10; // no fillstyle used 2776 break; 2777 } 2778 } 2779 if ( ( ( nLineFlags & 0x08 ) == 0 ) && ( ( nFillFlags & 0x10 ) == 0 ) ) // if there is no fillstyle and linestyle 2780 bHasShadow = sal_False; // we are turning shadow off. 2781 2782 if ( bHasShadow ) 2783 rSet.Put( SdrShadowItem( bHasShadow ) ); 2784 } 2785 ApplyLineAttributes( rSet, rObjData.eShapeType ); // #i28269# 2786 ApplyFillAttributes( rIn, rSet, rObjData ); 2787 if ( rObjData.eShapeType != mso_sptNil ) 2788 { 2789 ApplyCustomShapeGeometryAttributes( rIn, rSet, rObjData ); 2790 ApplyCustomShapeTextAttributes( rSet ); 2791 if ( rManager.GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL ) 2792 { 2793 if ( mnFix16Angle || ( rObjData.nSpFlags & SP_FFLIPV ) ) 2794 CheckAndCorrectExcelTextRotation( rIn, rSet, rObjData ); 2795 } 2796 } 2797 } 2798 2799 void DffPropertyReader::CheckAndCorrectExcelTextRotation( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const 2800 { 2801 sal_Bool bRotateTextWithShape = rObjData.bRotateTextWithShape; 2802 if ( rObjData.bOpt2 ) // sj: #158494# is the second property set available ? if then we have to check the xml data of 2803 { // the shape, because the textrotation of Excel 2003 and greater versions is stored there 2804 // (upright property of the textbox) 2805 if ( rManager.pSecPropSet->SeekToContent( DFF_Prop_metroBlob, rIn ) ) 2806 { 2807 sal_uInt32 nLen = rManager.pSecPropSet->GetPropertyValue( DFF_Prop_metroBlob ); 2808 if ( nLen ) 2809 { 2810 ::com::sun::star::uno::Sequence< sal_Int8 > aXMLDataSeq( nLen ); 2811 rIn.Read( aXMLDataSeq.getArray(), nLen ); 2812 ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInputStream 2813 ( new ::comphelper::SequenceInputStream( aXMLDataSeq ) ); 2814 try 2815 { 2816 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); 2817 if ( xFactory.is() ) 2818 { 2819 ::com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage 2820 ( ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( 2821 OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xFactory, sal_True ) ); 2822 if ( xStorage.is() ) 2823 { 2824 const rtl::OUString sDRS( RTL_CONSTASCII_USTRINGPARAM ( "drs" ) ); 2825 ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > 2826 xStorageDRS( xStorage->openStorageElement( sDRS, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) ); 2827 if ( xStorageDRS.is() ) 2828 { 2829 const rtl::OUString sShapeXML( RTL_CONSTASCII_USTRINGPARAM ( "shapexml.xml" ) ); 2830 ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xShapeXMLStream( xStorageDRS->openStreamElement( sShapeXML, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) ); 2831 if ( xShapeXMLStream.is() ) 2832 { 2833 ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xShapeXMLInputStream( xShapeXMLStream->getInputStream() ); 2834 if ( xShapeXMLInputStream.is() ) 2835 { 2836 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; 2837 sal_Int32 nBytesRead = xShapeXMLInputStream->readBytes( aSeq, 0x7fffffff ); 2838 if ( nBytesRead ) 2839 { // for only one property I spare to use a XML parser at this point, this 2840 // should be enhanced if needed 2841 2842 bRotateTextWithShape = sal_True; // using the correct xml default 2843 const char* pArry = reinterpret_cast< char* >( aSeq.getArray() ); 2844 const char* pUpright = "upright="; 2845 const char* pEnd = pArry + nBytesRead; 2846 const char* pPtr = pArry; 2847 while( ( pPtr + 12 ) < pEnd ) 2848 { 2849 if ( !memcmp( pUpright, pPtr, 8 ) ) 2850 { 2851 bRotateTextWithShape = ( pPtr[ 9 ] != '1' ) && ( pPtr[ 9 ] != 't' ); 2852 break; 2853 } 2854 else 2855 pPtr++; 2856 } 2857 } 2858 } 2859 } 2860 } 2861 } 2862 } 2863 } 2864 catch( com::sun::star::uno::Exception& ) 2865 { 2866 } 2867 } 2868 } 2869 } 2870 if ( !bRotateTextWithShape ) 2871 { 2872 const com::sun::star::uno::Any* pAny, aAny; 2873 SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)rSet.Get( SDRATTR_CUSTOMSHAPE_GEOMETRY )); 2874 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) ); 2875 pAny = aGeometryItem.GetPropertyValueByName( sTextRotateAngle ); 2876 double fExtraTextRotateAngle = 0.0; 2877 if ( pAny ) 2878 *pAny >>= fExtraTextRotateAngle; 2879 2880 if ( rManager.mnFix16Angle ) 2881 fExtraTextRotateAngle += mnFix16Angle / 100.0; 2882 if ( rObjData.nSpFlags & SP_FFLIPV ) 2883 fExtraTextRotateAngle -= 180.0; 2884 2885 com::sun::star::beans::PropertyValue aTextRotateAngle; 2886 aTextRotateAngle.Name = sTextRotateAngle; 2887 aTextRotateAngle.Value <<= fExtraTextRotateAngle; 2888 aGeometryItem.SetPropertyValue( aTextRotateAngle ); 2889 rSet.Put( aGeometryItem ); 2890 } 2891 } 2892 2893 //--------------------------------------------------------------------------- 2894 //- Record Manager ---------------------------------------------------------- 2895 //--------------------------------------------------------------------------- 2896 2897 DffRecordList::DffRecordList( DffRecordList* pList ) : 2898 nCount ( 0 ), 2899 nCurrent ( 0 ), 2900 pPrev ( pList ), 2901 pNext ( NULL ) 2902 { 2903 if ( pList ) 2904 pList->pNext = this; 2905 } 2906 2907 DffRecordList::~DffRecordList() 2908 { 2909 delete pNext; 2910 } 2911 2912 DffRecordManager::DffRecordManager() : 2913 DffRecordList ( NULL ), 2914 pCList ( (DffRecordList*)this ) 2915 { 2916 } 2917 2918 DffRecordManager::DffRecordManager( SvStream& rIn ) : 2919 DffRecordList ( NULL ), 2920 pCList ( (DffRecordList*)this ) 2921 { 2922 Consume( rIn ); 2923 } 2924 2925 DffRecordManager::~DffRecordManager() 2926 { 2927 }; 2928 2929 2930 void DffRecordManager::Consume( SvStream& rIn, sal_Bool bAppend, sal_uInt32 nStOfs ) 2931 { 2932 if ( !bAppend ) 2933 Clear(); 2934 sal_uInt32 nOldPos = rIn.Tell(); 2935 if ( !nStOfs ) 2936 { 2937 DffRecordHeader aHd; 2938 rIn >> aHd; 2939 if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER ) 2940 nStOfs = aHd.GetRecEndFilePos(); 2941 } 2942 if ( nStOfs ) 2943 { 2944 pCList = (DffRecordList*)this; 2945 while ( pCList->pNext ) 2946 pCList = pCList->pNext; 2947 while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <= nStOfs ) ) 2948 { 2949 if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE ) 2950 pCList = new DffRecordList( pCList ); 2951 rIn >> pCList->mHd[ pCList->nCount ]; 2952 pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn ); 2953 } 2954 rIn.Seek( nOldPos ); 2955 } 2956 } 2957 2958 void DffRecordManager::Clear() 2959 { 2960 pCList = (DffRecordList*)this; 2961 delete pNext, pNext = NULL; 2962 nCurrent = 0; 2963 nCount = 0; 2964 } 2965 2966 DffRecordHeader* DffRecordManager::Current() 2967 { 2968 DffRecordHeader* pRet = NULL; 2969 if ( pCList->nCurrent < pCList->nCount ) 2970 pRet = &pCList->mHd[ pCList->nCurrent ]; 2971 return pRet; 2972 } 2973 2974 DffRecordHeader* DffRecordManager::First() 2975 { 2976 DffRecordHeader* pRet = NULL; 2977 pCList = (DffRecordList*)this; 2978 if ( pCList->nCount ) 2979 { 2980 pCList->nCurrent = 0; 2981 pRet = &pCList->mHd[ 0 ]; 2982 } 2983 return pRet; 2984 } 2985 2986 DffRecordHeader* DffRecordManager::Next() 2987 { 2988 DffRecordHeader* pRet = NULL; 2989 sal_uInt32 nC = pCList->nCurrent + 1; 2990 if ( nC < pCList->nCount ) 2991 { 2992 pCList->nCurrent++; 2993 pRet = &pCList->mHd[ nC ]; 2994 } 2995 else if ( pCList->pNext ) 2996 { 2997 pCList = pCList->pNext; 2998 pCList->nCurrent = 0; 2999 pRet = &pCList->mHd[ 0 ]; 3000 } 3001 return pRet; 3002 } 3003 3004 DffRecordHeader* DffRecordManager::Prev() 3005 { 3006 DffRecordHeader* pRet = NULL; 3007 sal_uInt32 nCur = pCList->nCurrent; 3008 if ( !nCur && pCList->pPrev ) 3009 { 3010 pCList = pCList->pPrev; 3011 nCur = pCList->nCount; 3012 } 3013 if ( nCur-- ) 3014 { 3015 pCList->nCurrent = nCur; 3016 pRet = &pCList->mHd[ nCur ]; 3017 } 3018 return pRet; 3019 } 3020 3021 DffRecordHeader* DffRecordManager::Last() 3022 { 3023 DffRecordHeader* pRet = NULL; 3024 while ( pCList->pNext ) 3025 pCList = pCList->pNext; 3026 sal_uInt32 nCnt = pCList->nCount; 3027 if ( nCnt-- ) 3028 { 3029 pCList->nCurrent = nCnt; 3030 pRet = &pCList->mHd[ nCnt ]; 3031 } 3032 return pRet; 3033 } 3034 3035 sal_Bool DffRecordManager::SeekToContent( SvStream& rIn, sal_uInt16 nRecId, DffSeekToContentMode eMode ) 3036 { 3037 DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode ); 3038 if ( pHd ) 3039 { 3040 pHd->SeekToContent( rIn ); 3041 return sal_True; 3042 } 3043 else 3044 return sal_False; 3045 } 3046 3047 DffRecordHeader* DffRecordManager::GetRecordHeader( sal_uInt16 nRecId, DffSeekToContentMode eMode ) 3048 { 3049 sal_uInt32 nOldCurrent = pCList->nCurrent; 3050 DffRecordList* pOldList = pCList; 3051 DffRecordHeader* pHd; 3052 3053 if ( eMode == SEEK_FROM_BEGINNING ) 3054 pHd = First(); 3055 else 3056 pHd = Next(); 3057 3058 while ( pHd ) 3059 { 3060 if ( pHd->nRecType == nRecId ) 3061 break; 3062 pHd = Next(); 3063 } 3064 if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART ) 3065 { 3066 DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ]; 3067 pHd = First(); 3068 if ( pHd ) 3069 { 3070 while ( pHd != pBreak ) 3071 { 3072 if ( pHd->nRecType == nRecId ) 3073 break; 3074 pHd = Next(); 3075 } 3076 if ( pHd->nRecType != nRecId ) 3077 pHd = NULL; 3078 } 3079 } 3080 if ( !pHd ) 3081 { 3082 pCList = pOldList; 3083 pOldList->nCurrent = nOldCurrent; 3084 } 3085 return pHd; 3086 } 3087 3088 //--------------------------------------------------------------------------- 3089 // private Methoden 3090 //--------------------------------------------------------------------------- 3091 3092 struct EscherBlipCacheEntry 3093 { 3094 ByteString aUniqueID; 3095 sal_uInt32 nBlip; 3096 3097 EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) : 3098 aUniqueID( rUniqueID ), 3099 nBlip( nBlipId ) {} 3100 }; 3101 3102 void SvxMSDffManager::Scale( sal_Int32& rVal ) const 3103 { 3104 if ( bNeedMap ) 3105 rVal = BigMulDiv( rVal, nMapMul, nMapDiv ); 3106 } 3107 3108 void SvxMSDffManager::Scale( Point& rPos ) const 3109 { 3110 rPos.X() += nMapXOfs; 3111 rPos.Y() += nMapYOfs; 3112 if ( bNeedMap ) 3113 { 3114 rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv ); 3115 rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv ); 3116 } 3117 } 3118 3119 void SvxMSDffManager::Scale( Size& rSiz ) const 3120 { 3121 if ( bNeedMap ) 3122 { 3123 rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv ); 3124 rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv ); 3125 } 3126 } 3127 3128 void SvxMSDffManager::Scale( Rectangle& rRect ) const 3129 { 3130 rRect.Move( nMapXOfs, nMapYOfs ); 3131 if ( bNeedMap ) 3132 { 3133 rRect.Left() =BigMulDiv( rRect.Left() , nMapMul, nMapDiv ); 3134 rRect.Top() =BigMulDiv( rRect.Top() , nMapMul, nMapDiv ); 3135 rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv ); 3136 rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv ); 3137 } 3138 } 3139 3140 void SvxMSDffManager::Scale( Polygon& rPoly ) const 3141 { 3142 if ( !bNeedMap ) 3143 return; 3144 sal_uInt16 nPointAnz = rPoly.GetSize(); 3145 for ( sal_uInt16 nPointNum = 0; nPointNum < nPointAnz; nPointNum++ ) 3146 Scale( rPoly[ nPointNum ] ); 3147 } 3148 3149 void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const 3150 { 3151 if ( !bNeedMap ) 3152 return; 3153 sal_uInt16 nPolyAnz = rPoly.Count(); 3154 for ( sal_uInt16 nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ ) 3155 Scale( rPoly[ nPolyNum ] ); 3156 } 3157 3158 void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const 3159 { 3160 rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv ); 3161 } 3162 3163 sal_uInt32 SvxMSDffManager::ScalePt( sal_uInt32 nVal ) const 3164 { 3165 MapUnit eMap = pSdrModel->GetScaleUnit(); 3166 Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() ); 3167 long aMul = aFact.GetNumerator(); 3168 long aDiv = aFact.GetDenominator() * 65536; 3169 aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen 3170 return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() ); 3171 } 3172 3173 sal_Int32 SvxMSDffManager::ScalePoint( sal_Int32 nVal ) const 3174 { 3175 return BigMulDiv( nVal, nPntMul, nPntDiv ); 3176 }; 3177 3178 void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale) 3179 { 3180 pSdrModel = pModel; 3181 if( pModel && (0 < nApplicationScale) ) 3182 { 3183 // PPT arbeitet nur mit Einheiten zu 576DPI 3184 // WW hingegen verwendet twips, dh. 1440DPI. 3185 MapUnit eMap = pSdrModel->GetScaleUnit(); 3186 Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() ); 3187 long nMul=aFact.GetNumerator(); 3188 long nDiv=aFact.GetDenominator()*nApplicationScale; 3189 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen 3190 // Bei 100TH_MM -> 2540/576=635/144 3191 // Bei Twip -> 1440/576=5/2 3192 nMapMul = aFact.GetNumerator(); 3193 nMapDiv = aFact.GetDenominator(); 3194 bNeedMap = nMapMul!=nMapDiv; 3195 3196 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben 3197 // 1mm=36000emu, 1twip=635emu 3198 aFact=GetMapFactor(MAP_100TH_MM,eMap).X(); 3199 nMul=aFact.GetNumerator(); 3200 nDiv=aFact.GetDenominator()*360; 3201 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen 3202 // Bei 100TH_MM -> 1/360 3203 // Bei Twip -> 14,40/(25,4*360)=144/91440=1/635 3204 nEmuMul=aFact.GetNumerator(); 3205 nEmuDiv=aFact.GetDenominator(); 3206 3207 // Und noch was fuer typografische Points 3208 aFact=GetMapFactor(MAP_POINT,eMap).X(); 3209 nPntMul=aFact.GetNumerator(); 3210 nPntDiv=aFact.GetDenominator(); 3211 } 3212 else 3213 { 3214 pModel = 0; 3215 nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0; 3216 bNeedMap = sal_False; 3217 } 3218 } 3219 3220 sal_Bool SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, sal_uInt32 nId ) const 3221 { 3222 sal_Bool bRet = sal_False; 3223 if ( mpFidcls ) 3224 { 3225 sal_uInt32 nMerk = rSt.Tell(); 3226 sal_uInt32 nShapeId, nSec = ( nId >> 10 ) - 1; 3227 if ( nSec < mnIdClusters ) 3228 { 3229 sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid ); 3230 if ( nOfs ) 3231 { 3232 rSt.Seek( nOfs ); 3233 DffRecordHeader aEscherF002Hd; 3234 rSt >> aEscherF002Hd; 3235 sal_uLong nEscherF002End = aEscherF002Hd.GetRecEndFilePos(); 3236 DffRecordHeader aEscherObjListHd; 3237 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nEscherF002End ) ) 3238 { 3239 rSt >> aEscherObjListHd; 3240 if ( aEscherObjListHd.nRecVer != 0xf ) 3241 aEscherObjListHd.SeekToEndOfRecord( rSt ); 3242 else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer ) 3243 { 3244 DffRecordHeader aShapeHd; 3245 if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) ) 3246 { 3247 rSt >> nShapeId; 3248 if ( nId == nShapeId ) 3249 { 3250 aEscherObjListHd.SeekToBegOfRecord( rSt ); 3251 bRet = sal_True; 3252 break; 3253 } 3254 } 3255 aEscherObjListHd.SeekToEndOfRecord( rSt ); 3256 } 3257 } 3258 } 3259 } 3260 if ( !bRet ) 3261 rSt.Seek( nMerk ); 3262 } 3263 return bRet; 3264 } 3265 3266 FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, sal_uInt16 nRecId, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const 3267 { 3268 FASTBOOL bRet = sal_False; 3269 sal_uLong nFPosMerk = rSt.Tell(); // store FilePos to restore it later if necessary 3270 DffRecordHeader aHd; 3271 do 3272 { 3273 rSt >> aHd; 3274 3275 // check potential error reading and if seeking to the end of record is possible at all. 3276 // It is probably cheaper instead of doing the file seek operation 3277 if ( rSt.GetError() || ( aHd.GetRecEndFilePos() > nMaxFilePos ) ) 3278 { 3279 bRet= sal_False; 3280 break; 3281 } 3282 3283 if ( aHd.nRecType == nRecId ) 3284 { 3285 if ( nSkipCount ) 3286 nSkipCount--; 3287 else 3288 { 3289 bRet = sal_True; 3290 if ( pRecHd != NULL ) 3291 *pRecHd = aHd; 3292 else 3293 aHd.SeekToBegOfRecord( rSt ); 3294 } 3295 } 3296 if ( !bRet ) 3297 aHd.SeekToEndOfRecord( rSt ); 3298 } 3299 while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet ); 3300 if ( !bRet ) 3301 rSt.Seek( nFPosMerk ); // restore orginal FilePos 3302 return bRet; 3303 } 3304 3305 FASTBOOL SvxMSDffManager::SeekToRec2( sal_uInt16 nRecId1, sal_uInt16 nRecId2, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const 3306 { 3307 FASTBOOL bRet = sal_False; 3308 sal_uLong nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer ggf. spaetere Restauration 3309 DffRecordHeader aHd; 3310 do 3311 { 3312 rStCtrl >> aHd; 3313 if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 ) 3314 { 3315 if ( nSkipCount ) 3316 nSkipCount--; 3317 else 3318 { 3319 bRet = sal_True; 3320 if ( pRecHd ) 3321 *pRecHd = aHd; 3322 else 3323 aHd.SeekToBegOfRecord( rStCtrl ); 3324 } 3325 } 3326 if ( !bRet ) 3327 aHd.SeekToEndOfRecord( rStCtrl ); 3328 } 3329 while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet ); 3330 if ( !bRet ) 3331 rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren 3332 return bRet; 3333 } 3334 3335 3336 FASTBOOL SvxMSDffManager::GetColorFromPalette( sal_uInt16 /* nNum */, Color& rColor ) const 3337 { 3338 // diese Methode ist in der zum Excel-Import 3339 // abgeleiteten Klasse zu ueberschreiben... 3340 rColor.SetColor( COL_WHITE ); 3341 return sal_True; 3342 } 3343 3344 // sj: the documentation is not complete, especially in ppt the normal rgb for text 3345 // color is written as 0xfeRRGGBB, this can't be explained by the documentation, nearly 3346 // every bit in the upper code is set -> so there seems to be a special handling for 3347 // ppt text colors, i decided not to fix this in MSO_CLR_ToColor because of possible 3348 // side effects, instead MSO_TEXT_CLR_ToColor is called for PPT text colors, to map 3349 // the color code to something that behaves like the other standard color codes used by 3350 // fill and line color 3351 Color SvxMSDffManager::MSO_TEXT_CLR_ToColor( sal_uInt32 nColorCode ) const 3352 { 3353 // Fuer Textfarben: Header ist 0xfeRRGGBB 3354 if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 ) 3355 nColorCode &= 0x00ffffff; 3356 else 3357 { 3358 // for colorscheme colors the color index are the lower three bits of the upper byte 3359 if ( ( nColorCode & 0xf8000000 ) == 0 ) // this must be a colorscheme index 3360 { 3361 nColorCode >>= 24; 3362 nColorCode |= 0x8000000; 3363 } 3364 } 3365 return MSO_CLR_ToColor( nColorCode ); 3366 } 3367 3368 Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const 3369 { 3370 Color aColor( mnDefaultColor ); 3371 3372 // Fuer Textfarben: Header ist 0xfeRRGGBB 3373 if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 ) // sj: it needs to be checked if 0xfe is used in 3374 nColorCode &= 0x00ffffff; // other cases than ppt text -> if not this code can be removed 3375 3376 sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 ); 3377 3378 // sj: below change from 0x1b to 0x19 was done because of i84812 (0x02 -> rgb color), 3379 // now I have some problems to fix i104685 (there the color value is 0x02000000 whichs requires 3380 // a 0x2 scheme color to be displayed properly), the color docu seems to be incomplete 3381 if( nUpper & 0x19 ) // if( nUpper & 0x1f ) 3382 { 3383 if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) ) 3384 { 3385 // SCHEMECOLOR 3386 if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) ) 3387 { 3388 switch( nContentProperty ) 3389 { 3390 case DFF_Prop_pictureTransparent : 3391 case DFF_Prop_shadowColor : 3392 case DFF_Prop_fillBackColor : 3393 case DFF_Prop_fillColor : 3394 aColor = Color( COL_WHITE ); 3395 break; 3396 case DFF_Prop_lineColor : 3397 { 3398 aColor = Color( COL_BLACK ); 3399 } 3400 break; 3401 } 3402 } 3403 } 3404 else // SYSCOLOR 3405 { 3406 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 3407 3408 // sal_uInt16 nParameter = (sal_uInt8)( nColorCode >> 16); // SJ: nice compiler optimization bug on windows, though downcasting 3409 sal_uInt16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o 3410 sal_uInt16 nFunctionBits = (sal_uInt16)( ( nColorCode & 0x00000f00 ) >> 8 ); 3411 sal_uInt16 nAdditionalFlags = (sal_uInt16)( ( nColorCode & 0x0000f000) >> 8 ); 3412 sal_uInt16 nColorIndex = sal_uInt16(nColorCode & 0x00ff); 3413 sal_uInt32 nPropColor = 0; 3414 3415 sal_uInt16 nCProp = 0; 3416 3417 switch ( nColorIndex ) 3418 { 3419 case mso_syscolorButtonFace : aColor = rStyleSettings.GetFaceColor(); break; 3420 case mso_syscolorWindowText : aColor = rStyleSettings.GetWindowTextColor(); break; 3421 case mso_syscolorMenu : aColor = rStyleSettings.GetMenuColor(); break; 3422 case mso_syscolor3DLight : 3423 case mso_syscolorButtonHighlight : 3424 case mso_syscolorHighlight : aColor = rStyleSettings.GetHighlightColor(); break; 3425 case mso_syscolorHighlightText : aColor = rStyleSettings.GetHighlightTextColor(); break; 3426 case mso_syscolorCaptionText : aColor = rStyleSettings.GetMenuTextColor(); break; 3427 case mso_syscolorActiveCaption : aColor = rStyleSettings.GetHighlightColor(); break; 3428 case mso_syscolorButtonShadow : aColor = rStyleSettings.GetShadowColor(); break; 3429 case mso_syscolorButtonText : aColor = rStyleSettings.GetButtonTextColor(); break; 3430 case mso_syscolorGrayText : aColor = rStyleSettings.GetDeactiveColor(); break; 3431 case mso_syscolorInactiveCaption : aColor = rStyleSettings.GetDeactiveColor(); break; 3432 case mso_syscolorInactiveCaptionText : aColor = rStyleSettings.GetDeactiveColor(); break; 3433 case mso_syscolorInfoBackground : aColor = rStyleSettings.GetFaceColor(); break; 3434 case mso_syscolorInfoText : aColor = rStyleSettings.GetInfoTextColor(); break; 3435 case mso_syscolorMenuText : aColor = rStyleSettings.GetMenuTextColor(); break; 3436 case mso_syscolorScrollbar : aColor = rStyleSettings.GetFaceColor(); break; 3437 case mso_syscolorWindow : aColor = rStyleSettings.GetWindowColor(); break; 3438 case mso_syscolorWindowFrame : aColor = rStyleSettings.GetWindowColor(); break; 3439 3440 case mso_colorFillColor : 3441 { 3442 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); 3443 nCProp = DFF_Prop_fillColor; 3444 } 3445 break; 3446 case mso_colorLineOrFillColor : // ( use the line color only if there is a line ) 3447 { 3448 if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 ) 3449 { 3450 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 ); 3451 nCProp = DFF_Prop_lineColor; 3452 } 3453 else 3454 { 3455 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); 3456 nCProp = DFF_Prop_fillColor; 3457 } 3458 } 3459 break; 3460 case mso_colorLineColor : 3461 { 3462 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 ); 3463 nCProp = DFF_Prop_lineColor; 3464 } 3465 break; 3466 case mso_colorShadowColor : 3467 { 3468 nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 ); 3469 nCProp = DFF_Prop_shadowColor; 3470 } 3471 break; 3472 case mso_colorThis : // ( use this color ... ) 3473 { 3474 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //????????????? 3475 nCProp = DFF_Prop_fillColor; 3476 } 3477 break; 3478 case mso_colorFillBackColor : 3479 { 3480 nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff ); 3481 nCProp = DFF_Prop_fillBackColor; 3482 } 3483 break; 3484 case mso_colorLineBackColor : 3485 { 3486 nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff ); 3487 nCProp = DFF_Prop_lineBackColor; 3488 } 3489 break; 3490 case mso_colorFillThenLine : // ( use the fillcolor unless no fill and line ) 3491 { 3492 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //????????????? 3493 nCProp = DFF_Prop_fillColor; 3494 } 3495 break; 3496 case mso_colorIndexMask : // ( extract the color index ) ? 3497 { 3498 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //????????????? 3499 nCProp = DFF_Prop_fillColor; 3500 } 3501 break; 3502 } 3503 if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive 3504 aColor = MSO_CLR_ToColor( nPropColor, nCProp ); 3505 3506 if( nAdditionalFlags & 0x80 ) // make color gray 3507 { 3508 sal_uInt8 nZwi = aColor.GetLuminance(); 3509 aColor = Color( nZwi, nZwi, nZwi ); 3510 } 3511 switch( nFunctionBits ) 3512 { 3513 case 0x01 : // darken color by parameter 3514 { 3515 aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetRed() ) >> 8 ) ); 3516 aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) ); 3517 aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) ); 3518 } 3519 break; 3520 case 0x02 : // lighten color by parameter 3521 { 3522 sal_uInt16 nInvParameter = ( 0x00ff - nParameter ) * 0xff; 3523 aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) ); 3524 aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) ); 3525 aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) ); 3526 } 3527 break; 3528 case 0x03 : // add grey level RGB(p,p,p) 3529 { 3530 sal_Int16 nR = (sal_Int16)aColor.GetRed() + (sal_Int16)nParameter; 3531 sal_Int16 nG = (sal_Int16)aColor.GetGreen() + (sal_Int16)nParameter; 3532 sal_Int16 nB = (sal_Int16)aColor.GetBlue() + (sal_Int16)nParameter; 3533 if ( nR > 0x00ff ) 3534 nR = 0x00ff; 3535 if ( nG > 0x00ff ) 3536 nG = 0x00ff; 3537 if ( nB > 0x00ff ) 3538 nB = 0x00ff; 3539 aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB ); 3540 } 3541 break; 3542 case 0x04 : // substract grey level RGB(p,p,p) 3543 { 3544 sal_Int16 nR = (sal_Int16)aColor.GetRed() - (sal_Int16)nParameter; 3545 sal_Int16 nG = (sal_Int16)aColor.GetGreen() - (sal_Int16)nParameter; 3546 sal_Int16 nB = (sal_Int16)aColor.GetBlue() - (sal_Int16)nParameter; 3547 if ( nR < 0 ) 3548 nR = 0; 3549 if ( nG < 0 ) 3550 nG = 0; 3551 if ( nB < 0 ) 3552 nB = 0; 3553 aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB ); 3554 } 3555 break; 3556 case 0x05 : // substract from grey level RGB(p,p,p) 3557 { 3558 sal_Int16 nR = (sal_Int16)nParameter - (sal_Int16)aColor.GetRed(); 3559 sal_Int16 nG = (sal_Int16)nParameter - (sal_Int16)aColor.GetGreen(); 3560 sal_Int16 nB = (sal_Int16)nParameter - (sal_Int16)aColor.GetBlue(); 3561 if ( nR < 0 ) 3562 nR = 0; 3563 if ( nG < 0 ) 3564 nG = 0; 3565 if ( nB < 0 ) 3566 nB = 0; 3567 aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB ); 3568 } 3569 break; 3570 case 0x06 : // per component: black if < p, white if >= p 3571 { 3572 aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff ); 3573 aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff ); 3574 aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff ); 3575 } 3576 break; 3577 } 3578 if ( nAdditionalFlags & 0x40 ) // top-bit invert 3579 aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 ); 3580 3581 if ( nAdditionalFlags & 0x20 ) // invert color 3582 aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue()); 3583 } 3584 } 3585 else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) ) 3586 { // case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor 3587 GetColorFromPalette( nUpper, aColor ); 3588 } 3589 else // hart attributiert, eventuell mit Hinweis auf SYSTEMRGB 3590 aColor = Color( (sal_uInt8)nColorCode, (sal_uInt8)( nColorCode >> 8 ), (sal_uInt8)( nColorCode >> 16 ) ); 3591 return aColor; 3592 } 3593 3594 // sj: I just want to set a string for a text object that may contain multiple 3595 // paragraphs. If I now take a look at the follwing code I get the impression that 3596 // our outliner is too complicate to be used properly, 3597 void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const 3598 { 3599 SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj ); 3600 if ( pText ) 3601 { 3602 SdrOutliner& rOutliner = pText->ImpGetDrawOutliner(); 3603 rOutliner.Init( OUTLINERMODE_TEXTOBJECT ); 3604 3605 sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode(); 3606 rOutliner.SetUpdateMode( sal_False ); 3607 rOutliner.SetVertical( pText->IsVerticalWriting() ); 3608 3609 sal_uInt16 nParaIndex = 0; 3610 sal_uInt32 nParaSize; 3611 const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer(); 3612 const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len(); 3613 3614 while( pBuf < pEnd ) 3615 { 3616 pCurrent = pBuf; 3617 3618 for ( nParaSize = 0; pBuf < pEnd; ) 3619 { 3620 sal_Unicode nChar = *pBuf++; 3621 if ( nChar == 0xa ) 3622 { 3623 if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) ) 3624 pBuf++; 3625 break; 3626 } 3627 else if ( nChar == 0xd ) 3628 { 3629 if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) ) 3630 pBuf++; 3631 break; 3632 } 3633 else 3634 nParaSize++; 3635 } 3636 ESelection aSelection( nParaIndex, 0, nParaIndex, 0 ); 3637 String aParagraph( pCurrent, (sal_uInt16)nParaSize ); 3638 if ( !nParaIndex && !aParagraph.Len() ) // SJ: we are crashing if the first paragraph is empty ? 3639 aParagraph += (sal_Unicode)' '; // otherwise these two lines can be removed. 3640 rOutliner.Insert( aParagraph, nParaIndex, 0 ); 3641 rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() ); 3642 3643 SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() ); 3644 if ( !aSelection.nStartPos ) 3645 aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, sal_False ) ); 3646 aSelection.nStartPos = 0; 3647 rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection ); 3648 nParaIndex++; 3649 } 3650 OutlinerParaObject* pNewText = rOutliner.CreateParaObject(); 3651 rOutliner.Clear(); 3652 rOutliner.SetUpdateMode( bOldUpdateMode ); 3653 pText->SetOutlinerParaObject( pNewText ); 3654 } 3655 } 3656 3657 //static 3658 void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr, 3659 sal_uLong nRecLen, FASTBOOL bUniCode ) 3660 { 3661 sal_uInt16 nLen = (sal_uInt16)nRecLen; 3662 if( nLen ) 3663 { 3664 if ( bUniCode ) 3665 nLen >>= 1; 3666 3667 String sBuf; 3668 sal_Unicode* pBuf = sBuf.AllocBuffer( nLen ); 3669 3670 if( bUniCode ) 3671 { 3672 rIn.Read( (sal_Char*)pBuf, nLen << 1 ); 3673 3674 #ifdef OSL_BIGENDIAN 3675 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf ) 3676 *pBuf = SWAPSHORT( *pBuf ); 3677 #endif // ifdef OSL_BIGENDIAN 3678 } 3679 else 3680 { 3681 // use the String-Data as buffer for the 8bit characters and 3682 // change then all to unicode 3683 sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen; 3684 rIn.Read( (sal_Char*)pReadPos, nLen ); 3685 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos ) 3686 *pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 ); 3687 } 3688 3689 rStr = sBuf.EraseTrailingChars( 0 ); 3690 } 3691 else 3692 rStr.Erase(); 3693 } 3694 3695 SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const 3696 { 3697 SdrObject* pRet = NULL; 3698 String aObjectText; 3699 String aFontName; 3700 sal_Bool bTextRotate = sal_False; 3701 3702 ((SvxMSDffManager*)this)->mnFix16Angle = 0; // we don't want to use this property in future 3703 if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) ) 3704 MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True ); 3705 if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) ) 3706 MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True ); 3707 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) 3708 { 3709 // Text ist senkrecht formatiert, Box Kippen 3710 sal_Int32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1; 3711 sal_Int32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1; 3712 Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight, 3713 rBoundRect.Top() + nHalfHeight - nHalfWidth); 3714 Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() ); 3715 Rectangle aNewRect( aTopLeft, aNewSize ); 3716 rBoundRect = aNewRect; 3717 3718 String aSrcText( aObjectText ); 3719 aObjectText.Erase(); 3720 for( sal_uInt16 a = 0; a < aSrcText.Len(); a++ ) 3721 { 3722 aObjectText += aSrcText.GetChar( a ); 3723 aObjectText += '\n'; 3724 } 3725 rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) ); 3726 bTextRotate = sal_True; 3727 } 3728 if ( aObjectText.Len() ) 3729 { // FontWork-Objekt Mit dem Text in aObjectText erzeugen 3730 SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect ); 3731 if( pNewObj ) 3732 { 3733 pNewObj->SetModel( pSdrModel ); 3734 ((SdrRectObj*)pNewObj)->SetText( aObjectText ); 3735 SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL; 3736 rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) ); 3737 rSet.Put( SdrTextAutoGrowHeightItem( sal_False ) ); 3738 rSet.Put( SdrTextAutoGrowWidthItem( sal_False ) ); 3739 rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(), 3740 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO )); 3741 3742 pNewObj->SetMergedItemSet(rSet); 3743 3744 pRet = pNewObj->ConvertToPolyObj( sal_False, sal_False ); 3745 if( !pRet ) 3746 pRet = pNewObj; 3747 else 3748 { 3749 pRet->NbcSetSnapRect( rBoundRect ); 3750 SdrObject::Free( pNewObj ); 3751 } 3752 if( bTextRotate ) 3753 { 3754 double a = 9000 * nPi180; 3755 pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) ); 3756 } 3757 } 3758 } 3759 return pRet; 3760 } 3761 3762 static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted) 3763 { 3764 MapMode aPrefMapMode(rGraf.GetPrefMapMode()); 3765 if (aPrefMapMode == aWanted) 3766 return rGraf.GetPrefSize(); 3767 Size aRetSize; 3768 if (aPrefMapMode == MAP_PIXEL) 3769 { 3770 aRetSize = Application::GetDefaultDevice()->PixelToLogic( 3771 rGraf.GetPrefSize(), aWanted); 3772 } 3773 else 3774 { 3775 aRetSize = Application::GetDefaultDevice()->LogicToLogic( 3776 rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted); 3777 } 3778 return aRetSize; 3779 } 3780 3781 // sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf, 3782 // otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem 3783 static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf ) 3784 { 3785 sal_Int32 nCropTop = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 ); 3786 sal_Int32 nCropBottom = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 ); 3787 sal_Int32 nCropLeft = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 ); 3788 sal_Int32 nCropRight = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 ); 3789 3790 if( nCropTop || nCropBottom || nCropLeft || nCropRight ) 3791 { 3792 double fFactor; 3793 Size aCropSize; 3794 BitmapEx aCropBitmap; 3795 sal_uInt32 nTop( 0 ), nBottom( 0 ), nLeft( 0 ), nRight( 0 ); 3796 3797 if ( pSet ) // use crop attributes ? 3798 aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM ); 3799 else 3800 { 3801 aCropBitmap = rGraf.GetBitmapEx(); 3802 aCropSize = aCropBitmap.GetSizePixel(); 3803 } 3804 if ( nCropTop ) 3805 { 3806 fFactor = (double)nCropTop / 65536.0; 3807 nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 ); 3808 } 3809 if ( nCropBottom ) 3810 { 3811 fFactor = (double)nCropBottom / 65536.0; 3812 nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 ); 3813 } 3814 if ( nCropLeft ) 3815 { 3816 fFactor = (double)nCropLeft / 65536.0; 3817 nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 ); 3818 } 3819 if ( nCropRight ) 3820 { 3821 fFactor = (double)nCropRight / 65536.0; 3822 nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 ); 3823 } 3824 if ( pSet ) // use crop attributes ? 3825 pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) ); 3826 else 3827 { 3828 Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom ); 3829 aCropBitmap.Crop( aCropRect ); 3830 rGraf = aCropBitmap; 3831 } 3832 } 3833 } 3834 3835 SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, const DffObjData& rObjData ) const 3836 { 3837 SdrObject* pRet = NULL; 3838 String aFileName; 3839 String aLinkFileName, aLinkFilterName; 3840 Rectangle aVisArea; 3841 3842 MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault ); 3843 sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 ); 3844 sal_Bool bGrfRead = sal_False, 3845 3846 // Grafik verlinkt 3847 bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile ); 3848 { 3849 Graphic aGraf; // be sure this graphic is deleted before swapping out 3850 if( SeekToContent( DFF_Prop_pibName, rSt ) ) 3851 MSDFFReadZString( rSt, aFileName, GetPropertyValue( DFF_Prop_pibName ), sal_True ); 3852 3853 // UND, ODER folgendes: 3854 if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded 3855 { 3856 bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea ); 3857 if ( !bGrfRead ) 3858 { 3859 /* 3860 Still no luck, lets look at the end of this record for a FBSE pool, 3861 this fallback is a specific case for how word does it sometimes 3862 */ 3863 rObjData.rSpHd.SeekToEndOfRecord( rSt ); 3864 DffRecordHeader aHd; 3865 rSt >> aHd; 3866 if( DFF_msofbtBSE == aHd.nRecType ) 3867 { 3868 const sal_uLong nSkipBLIPLen = 20; 3869 const sal_uLong nSkipShapePos = 4; 3870 const sal_uLong nSkipBLIP = 4; 3871 const sal_uLong nSkip = 3872 nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP; 3873 3874 if (nSkip <= aHd.nRecLen) 3875 { 3876 rSt.SeekRel(nSkip); 3877 if (0 == rSt.GetError()) 3878 bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea ); 3879 } 3880 } 3881 } 3882 } 3883 if ( bGrfRead ) 3884 { 3885 // the writer is doing it's own cropping, so this part affects only impress and calc 3886 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS ) 3887 lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf ); 3888 3889 if ( IsProperty( DFF_Prop_pictureTransparent ) ) 3890 { 3891 sal_uInt32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 ); 3892 3893 if ( aGraf.GetType() == GRAPHIC_BITMAP ) 3894 { 3895 BitmapEx aBitmapEx( aGraf.GetBitmapEx() ); 3896 Bitmap aBitmap( aBitmapEx.GetBitmap() ); 3897 Bitmap aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) ); 3898 if ( aBitmapEx.IsTransparent() ) 3899 aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR ); 3900 aGraf = BitmapEx( aBitmap, aMask ); 3901 } 3902 } 3903 3904 sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 ); 3905 /* 3906 0x10000 is msoffice 50% 3907 < 0x10000 is in units of 1/50th of 0x10000 per 1% 3908 > 0x10000 is in units where 3909 a msoffice x% is stored as 50/(100-x) * 0x10000 3910 3911 plus, a (ui) microsoft % ranges from 0 to 100, OOO 3912 from -100 to 100, so also normalize into that range 3913 */ 3914 if ( nContrast > 0x10000 ) 3915 { 3916 double fX = nContrast; 3917 fX /= 0x10000; 3918 fX /= 51; // 50 + 1 to round 3919 fX = 1/fX; 3920 nContrast = static_cast<sal_Int32>(fX); 3921 nContrast -= 100; 3922 nContrast = -nContrast; 3923 nContrast = (nContrast-50)*2; 3924 } 3925 else if ( nContrast == 0x10000 ) 3926 nContrast = 0; 3927 else 3928 { 3929 nContrast *= 101; //100 + 1 to round 3930 nContrast /= 0x10000; 3931 nContrast -= 100; 3932 } 3933 sal_Int16 nBrightness = (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 ); 3934 sal_Int32 nGamma = GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 ); 3935 GraphicDrawMode eDrawMode = GRAPHICDRAWMODE_STANDARD; 3936 switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 ) 3937 { 3938 case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break; 3939 case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break; 3940 case 0 : 3941 { 3942 //office considers the converted values of (in OOo) 70 to be the 3943 //"watermark" values, which can vary slightly due to rounding from the 3944 //above values 3945 if (( nContrast == -70 ) && ( nBrightness == 70 )) 3946 { 3947 nContrast = 0; 3948 nBrightness = 0; 3949 eDrawMode = GRAPHICDRAWMODE_WATERMARK; 3950 }; 3951 } 3952 break; 3953 } 3954 3955 if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) ) 3956 { 3957 if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ) 3958 { 3959 if ( nBrightness ) 3960 rSet.Put( SdrGrafLuminanceItem( nBrightness ) ); 3961 if ( nContrast ) 3962 rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) ); 3963 if ( nGamma != 0x10000 ) 3964 rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) ); 3965 if ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) 3966 rSet.Put( SdrGrafModeItem( eDrawMode ) ); 3967 } 3968 else 3969 { 3970 if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK ) 3971 { 3972 nContrast = 60; 3973 nBrightness = 70; 3974 eDrawMode = GRAPHICDRAWMODE_STANDARD; 3975 } 3976 switch ( aGraf.GetType() ) 3977 { 3978 case GRAPHIC_BITMAP : 3979 { 3980 BitmapEx aBitmapEx( aGraf.GetBitmapEx() ); 3981 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) ) 3982 aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False ); 3983 if ( eDrawMode == GRAPHICDRAWMODE_GREYS ) 3984 aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS ); 3985 else if ( eDrawMode == GRAPHICDRAWMODE_MONO ) 3986 aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD ); 3987 aGraf = aBitmapEx; 3988 3989 } 3990 break; 3991 3992 case GRAPHIC_GDIMETAFILE : 3993 { 3994 GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() ); 3995 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) ) 3996 aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False ); 3997 if ( eDrawMode == GRAPHICDRAWMODE_GREYS ) 3998 aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS ); 3999 else if ( eDrawMode == GRAPHICDRAWMODE_MONO ) 4000 aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD ); 4001 aGraf = aGdiMetaFile; 4002 } 4003 break; 4004 default: break; 4005 } 4006 } 4007 } 4008 } 4009 4010 // sollte es ein OLE-Object sein? 4011 if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) ) 4012 { 4013 // TODO/LATER: in future probably the correct aspect should be provided here 4014 sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT; 4015 // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method 4016 pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, rObjData.aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect ); 4017 // <-- 4018 } 4019 if( !pRet ) 4020 { 4021 pRet = new SdrGrafObj; 4022 if( bGrfRead ) 4023 ((SdrGrafObj*)pRet)->SetGraphic( aGraf ); 4024 4025 if( bLinkGrf && !bGrfRead ) // sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then 4026 { // we do not need to set a link. TODO: not to lose the information where the graphic is linked from 4027 INetURLObject aAbsURL; 4028 if ( !INetURLObject( maBaseURL ).GetNewAbsURL( ByteString( aFileName, RTL_TEXTENCODING_UTF8 ), &aAbsURL ) ) 4029 { 4030 String aValidURL; 4031 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aFileName, aValidURL ) ) 4032 aAbsURL = INetURLObject( aValidURL ); 4033 } 4034 if( aAbsURL.GetProtocol() != INET_PROT_NOT_VALID ) 4035 { 4036 GraphicFilter* pGrfFilter = GraphicFilter::GetGraphicFilter(); 4037 aLinkFilterName = pGrfFilter->GetImportFormatName( 4038 pGrfFilter->GetImportFormatNumberForShortName( aAbsURL.getExtension() ) ); 4039 aLinkFileName = aAbsURL.GetMainURL( INetURLObject::DECODE_TO_IURI ); 4040 } 4041 else 4042 aLinkFileName = aFileName; 4043 } 4044 } 4045 4046 // set the size from BLIP if there is one 4047 if ( pRet && bGrfRead && !aVisArea.IsEmpty() ) 4048 pRet->SetBLIPSizeRectangle( aVisArea ); 4049 4050 if ( !pRet->GetName().Len() ) // SJ 22.02.00 : PPT OLE IMPORT: 4051 { // name is already set in ImportOLE !! 4052 // JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active 4053 if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment ) 4054 { 4055 INetURLObject aURL; 4056 aURL.SetSmartURL( aFileName ); 4057 pRet->SetName( aURL.getBase() ); 4058 } 4059 else 4060 pRet->SetName( aFileName ); 4061 } 4062 } 4063 pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich 4064 pRet->SetLogicRect( rObjData.aBoundRect ); 4065 4066 if ( pRet->ISA( SdrGrafObj ) ) 4067 { 4068 if( aLinkFileName.Len() ) 4069 ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName ); 4070 4071 if ( bLinkGrf && !bGrfRead ) 4072 { 4073 ((SdrGrafObj*)pRet)->ForceSwapIn(); 4074 Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic()); 4075 lcl_ApplyCropping( *this, &rSet, aGraf ); 4076 } 4077 ((SdrGrafObj*)pRet)->ForceSwapOut(); 4078 } 4079 4080 return pRet; 4081 } 4082 4083 // PptSlidePersistEntry& rPersistEntry, SdPage* pPage 4084 SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData, 4085 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId ) 4086 { 4087 SdrObject* pRet = NULL; 4088 DffRecordHeader aObjHd; 4089 rSt >> aObjHd; 4090 if ( aObjHd.nRecType == DFF_msofbtSpgrContainer ) 4091 { 4092 pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId ); 4093 } 4094 else if ( aObjHd.nRecType == DFF_msofbtSpContainer ) 4095 { 4096 pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId ); 4097 } 4098 aObjHd.SeekToBegOfRecord( rSt ); // FilePos restaurieren 4099 return pRet; 4100 } 4101 4102 SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData, 4103 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, 4104 int nCalledByGroup, sal_Int32* pShapeId ) 4105 { 4106 SdrObject* pRet = NULL; 4107 4108 if( pShapeId ) 4109 *pShapeId = 0; 4110 4111 rHd.SeekToContent( rSt ); 4112 DffRecordHeader aRecHd; // the first atom has to be the SpContainer for the GroupObject 4113 rSt >> aRecHd; 4114 if ( aRecHd.nRecType == DFF_msofbtSpContainer ) 4115 { 4116 sal_Int32 nGroupRotateAngle = 0; 4117 sal_Int32 nSpFlags = 0; 4118 mnFix16Angle = 0; 4119 aRecHd.SeekToBegOfRecord( rSt ); 4120 pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId ); 4121 if ( pRet ) 4122 { 4123 nSpFlags = nGroupShapeFlags; 4124 nGroupRotateAngle = mnFix16Angle; 4125 4126 Rectangle aClientRect( rClientRect ); 4127 4128 Rectangle aGlobalChildRect; 4129 if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() ) 4130 aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect ); 4131 else 4132 aGlobalChildRect = rGlobalChildRect; 4133 4134 if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 ) 4135 || ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) ) 4136 { 4137 sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1; 4138 sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1; 4139 Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight, 4140 aClientRect.Top() + nHalfHeight - nHalfWidth ); 4141 Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() ); 4142 Rectangle aNewRect( aTopLeft, aNewSize ); 4143 aClientRect = aNewRect; 4144 } 4145 4146 // now importing the inner objects of the group 4147 aRecHd.SeekToEndOfRecord( rSt ); 4148 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4149 { 4150 DffRecordHeader aRecHd2; 4151 rSt >> aRecHd2; 4152 if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer ) 4153 { 4154 Rectangle aGroupClientAnchor, aGroupChildAnchor; 4155 GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect ); 4156 aRecHd2.SeekToBegOfRecord( rSt ); 4157 sal_Int32 nShapeId; 4158 SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId ); 4159 if ( pTmp ) 4160 { 4161 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp ); 4162 if( nShapeId ) 4163 insertShapeId( nShapeId, pTmp ); 4164 } 4165 } 4166 else if ( aRecHd2.nRecType == DFF_msofbtSpContainer ) 4167 { 4168 aRecHd2.SeekToBegOfRecord( rSt ); 4169 sal_Int32 nShapeId; 4170 SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId ); 4171 if ( pTmp ) 4172 { 4173 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp ); 4174 if( nShapeId ) 4175 insertShapeId( nShapeId, pTmp ); 4176 } 4177 } 4178 aRecHd2.SeekToEndOfRecord( rSt ); 4179 } 4180 4181 // pRet->NbcSetSnapRect( aGroupBound ); 4182 if ( nGroupRotateAngle ) 4183 { 4184 double a = nGroupRotateAngle * nPi180; 4185 pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) ); 4186 } 4187 if ( nSpFlags & SP_FFLIPV ) // Vertikal gespiegelt? 4188 { // BoundRect in aBoundRect 4189 Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 ); 4190 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4191 pRet->NbcMirror( aLeft, aRight ); 4192 } 4193 if ( nSpFlags & SP_FFLIPH ) // Horizontal gespiegelt? 4194 { // BoundRect in aBoundRect 4195 Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() ); 4196 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4197 pRet->NbcMirror( aTop, aBottom ); 4198 } 4199 } 4200 } 4201 return pRet; 4202 } 4203 4204 SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData, 4205 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, 4206 int nCalledByGroup, sal_Int32* pShapeId ) 4207 { 4208 SdrObject* pRet = NULL; 4209 4210 if( pShapeId ) 4211 *pShapeId = 0; 4212 4213 rHd.SeekToBegOfRecord( rSt ); 4214 DffObjData aObjData( rHd, rClientRect, nCalledByGroup ); 4215 aObjData.bRotateTextWithShape = ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL ) == 0; 4216 maShapeRecords.Consume( rSt, sal_False ); 4217 aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING ); 4218 if ( aObjData.bShapeType ) 4219 { 4220 rSt >> aObjData.nShapeId 4221 >> aObjData.nSpFlags; 4222 aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance; 4223 } 4224 else 4225 { 4226 aObjData.nShapeId = 0; 4227 aObjData.nSpFlags = 0; 4228 aObjData.eShapeType = mso_sptNil; 4229 } 4230 4231 if( pShapeId ) 4232 *pShapeId = aObjData.nShapeId; 4233 4234 if ( mbTracing ) 4235 mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP 4236 ? rtl::OUString::createFromAscii( "GroupShape" ) 4237 : rtl::OUString::createFromAscii( "Shape" ), 4238 rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) ); 4239 aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART ); 4240 if ( aObjData.bOpt ) 4241 { 4242 maShapeRecords.Current()->SeekToBegOfRecord( rSt ); 4243 #ifdef DBG_AUTOSHAPE 4244 ReadPropSet( rSt, pClientData, (sal_uInt32)aObjData.eShapeType ); 4245 #else 4246 ReadPropSet( rSt, pClientData ); 4247 #endif 4248 } 4249 else 4250 { 4251 InitializePropSet( DFF_msofbtOPT ); // get the default PropSet 4252 ( (DffPropertyReader*) this )->mnFix16Angle = 0; 4253 } 4254 aObjData.bOpt2 = maShapeRecords.SeekToContent( rSt, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ); 4255 if ( aObjData.bOpt2 ) 4256 { 4257 maShapeRecords.Current()->SeekToBegOfRecord( rSt ); 4258 pSecPropSet = new DffPropertyReader( *this ); 4259 pSecPropSet->ReadPropSet( rSt, NULL ); 4260 } 4261 4262 aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART ); 4263 if ( aObjData.bChildAnchor ) 4264 { 4265 sal_Int32 l, o, r, u; 4266 rSt >> l >> o >> r >> u; 4267 Scale( l ); 4268 Scale( o ); 4269 Scale( r ); 4270 Scale( u ); 4271 aObjData.aChildAnchor = Rectangle( l, o, r, u ); 4272 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() ) 4273 { 4274 double fl = l; 4275 double fo = o; 4276 double fWidth = r - l; 4277 double fHeight= u - o; 4278 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth(); 4279 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight(); 4280 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left(); 4281 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top(); 4282 fWidth *= fXScale; 4283 fHeight *= fYScale; 4284 aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) ); 4285 } 4286 } 4287 4288 aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART ); 4289 if ( aObjData.bClientAnchor ) 4290 ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData ); 4291 4292 if ( aObjData.bChildAnchor ) 4293 aObjData.aBoundRect = aObjData.aChildAnchor; 4294 4295 if ( aObjData.nSpFlags & SP_FBACKGROUND ) 4296 aObjData.aBoundRect = Rectangle( Point(), Size( 1, 1 ) ); 4297 4298 Rectangle aTextRect; 4299 if ( !aObjData.aBoundRect.IsEmpty() ) 4300 { // Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde 4301 if( mnFix16Angle ) 4302 { 4303 long nAngle = mnFix16Angle; 4304 if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) ) 4305 { 4306 sal_Int32 nHalfWidth = ( aObjData.aBoundRect.GetWidth() + 1 ) >> 1; 4307 sal_Int32 nHalfHeight = ( aObjData.aBoundRect.GetHeight() + 1 ) >> 1; 4308 Point aTopLeft( aObjData.aBoundRect.Left() + nHalfWidth - nHalfHeight, 4309 aObjData.aBoundRect.Top() + nHalfHeight - nHalfWidth ); 4310 Size aNewSize( aObjData.aBoundRect.GetHeight(), aObjData.aBoundRect.GetWidth() ); 4311 Rectangle aNewRect( aTopLeft, aNewSize ); 4312 aObjData.aBoundRect = aNewRect; 4313 } 4314 } 4315 aTextRect = aObjData.aBoundRect; 4316 FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) || 4317 IsProperty( DFF_Prop_pibName ) || 4318 IsProperty( DFF_Prop_pibFlags ); 4319 4320 if ( aObjData.nSpFlags & SP_FGROUP ) 4321 { 4322 pRet = new SdrObjGroup; 4323 /* After CWS aw033 has been integrated, an empty group object 4324 cannot store its resulting bounding rectangle anymore. We have 4325 to return this rectangle via rClientRect now, but only, if 4326 caller has not passed an own bounding ractangle. */ 4327 if ( rClientRect.IsEmpty() ) 4328 rClientRect = aObjData.aBoundRect; 4329 nGroupShapeFlags = aObjData.nSpFlags; // #73013# 4330 } 4331 else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic ) 4332 { 4333 SfxItemSet aSet( pSdrModel->GetItemPool() ); 4334 4335 sal_Bool bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) ); 4336 sal_Bool bIsCustomShape = sal_False; 4337 sal_Int32 nObjectRotation = mnFix16Angle; 4338 sal_uInt32 nSpFlags = aObjData.nSpFlags; 4339 4340 if ( bGraphic ) 4341 { 4342 pRet = ImportGraphic( rSt, aSet, aObjData ); // SJ: #68396# is no longer true (fixed in ppt2000) 4343 ApplyAttributes( rSt, aSet, aObjData ); 4344 pRet->SetMergedItemSet(aSet); 4345 } 4346 else if ( aObjData.eShapeType == mso_sptLine ) 4347 { 4348 basegfx::B2DPolygon aPoly; 4349 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Left(), aObjData.aBoundRect.Top())); 4350 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Right(), aObjData.aBoundRect.Bottom())); 4351 pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly)); 4352 pRet->SetModel( pSdrModel ); 4353 ApplyAttributes( rSt, aSet, aObjData ); 4354 pRet->SetMergedItemSet(aSet); 4355 } 4356 else 4357 { 4358 if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) ) 4359 { 4360 4361 ApplyAttributes( rSt, aSet, aObjData ); 4362 4363 // the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute 4364 // aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) ); 4365 pRet = new SdrObjCustomShape(); 4366 pRet->SetModel( pSdrModel ); 4367 4368 sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0; 4369 4370 // in case of a FontWork, the text is set by the escher import 4371 if ( bIsFontwork ) 4372 { 4373 String aObjectText; 4374 String aFontName; 4375 MSO_GeoTextAlign eGeoTextAlign; 4376 4377 if ( SeekToContent( DFF_Prop_gtextFont, rSt ) ) 4378 { 4379 SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL); 4380 GetDefaultFonts( aLatin, aAsian, aComplex ); 4381 4382 MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True ); 4383 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(), 4384 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO )); 4385 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(), 4386 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) ); 4387 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(), 4388 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) ); 4389 } 4390 4391 // SJ: applying fontattributes for Fontwork : 4392 if ( IsHardAttribute( DFF_Prop_gtextFItalic ) ) 4393 aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) ); 4394 4395 if ( IsHardAttribute( DFF_Prop_gtextFBold ) ) 4396 aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); 4397 4398 // SJ TODO: Vertical Writing is not correct, instead this should be 4399 // replaced through "CharacterRotation" by 90�, therefore a new Item has to be 4400 // supported by svx core, api and xml file format 4401 ((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 ); 4402 4403 if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) ) 4404 { 4405 MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True ); 4406 ReadObjText( aObjectText, pRet ); 4407 } 4408 4409 eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) ); 4410 { 4411 SdrTextHorzAdjust eHorzAdjust; 4412 switch( eGeoTextAlign ) 4413 { 4414 case mso_alignTextLetterJust : 4415 case mso_alignTextWordJust : 4416 case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break; 4417 default: 4418 case mso_alignTextInvalid : 4419 case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break; 4420 case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break; 4421 case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break; 4422 } 4423 aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) ); 4424 4425 SdrFitToSizeType eFTS = SDRTEXTFIT_NONE; 4426 if ( eGeoTextAlign == mso_alignTextStretch ) 4427 eFTS = SDRTEXTFIT_ALLLINES; 4428 aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) ); 4429 } 4430 if ( IsProperty( DFF_Prop_gtextSpacing ) ) 4431 { 4432 sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655; 4433 if ( nTextWidth != 100 ) 4434 aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) ); 4435 } 4436 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 ) // SJ: Font Kerning On ? 4437 aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) ); 4438 } 4439 pRet->SetMergedItemSet( aSet ); 4440 4441 // sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set 4442 // proper text directions, instead the text default is depending to the string. 4443 // so we have to calculate the a text direction from string: 4444 if ( bIsFontwork ) 4445 { 4446 OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject(); 4447 if ( pParaObj ) 4448 { 4449 SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner(); 4450 sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode(); 4451 SdrModel* pModel = pRet->GetModel(); 4452 if ( pModel ) 4453 rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() ); 4454 rOutliner.SetUpdateMode( sal_False ); 4455 rOutliner.SetText( *pParaObj ); 4456 VirtualDevice aVirDev( 1 ); 4457 aVirDev.SetMapMode( MAP_100TH_MM ); 4458 sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount(); 4459 if ( nParagraphs ) 4460 { 4461 sal_Bool bCreateNewParaObject = sal_False; 4462 for ( i = 0; i < nParagraphs; i++ ) 4463 { 4464 sal_Bool bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN ); 4465 if ( bIsRTL ) 4466 { 4467 SfxItemSet aSet2( rOutliner.GetParaAttribs( (sal_uInt16)i ) ); 4468 aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) ); 4469 rOutliner.SetParaAttribs( (sal_uInt16)i, aSet2 ); 4470 bCreateNewParaObject = sal_True; 4471 } 4472 } 4473 if ( bCreateNewParaObject ) 4474 { 4475 OutlinerParaObject* pNewText = rOutliner.CreateParaObject(); 4476 rOutliner.Init( OUTLINERMODE_TEXTOBJECT ); 4477 ((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText ); 4478 } 4479 } 4480 rOutliner.Clear(); 4481 rOutliner.SetUpdateMode( bOldUpdateMode ); 4482 } 4483 } 4484 4485 // mso_sptArc special treating: 4486 // sj: since we actually can't render the arc because of its weird SnapRect settings, 4487 // we will create a new CustomShape, that can be saved/loaded without problems. 4488 // We will change the shape type, so this code applys only if importing arcs from msoffice. 4489 if ( aObjData.eShapeType == mso_sptArc ) 4490 { 4491 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); 4492 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) ); 4493 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) ); 4494 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) ); 4495 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) ); 4496 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); 4497 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) ); 4498 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); 4499 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates; 4500 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues; 4501 4502 // before clearing the GeometryItem we have to store the current Coordinates 4503 const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates ); 4504 Rectangle aPolyBoundRect; 4505 if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) ) 4506 { 4507 sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength(); 4508 XPolygon aXP( (sal_uInt16)nNumElemVert ); 4509 // const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray(); 4510 for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ ) 4511 { 4512 Point aP; 4513 sal_Int32 nX = 0, nY = 0; 4514 seqCoordinates[ nPtNum ].First.Value >>= nX; 4515 seqCoordinates[ nPtNum ].Second.Value >>= nY; 4516 aP.X() = nX; 4517 aP.Y() = nY; 4518 aXP[ (sal_uInt16)nPtNum ] = aP; 4519 } 4520 aPolyBoundRect = Rectangle( aXP.GetBoundRect() ); 4521 } 4522 else 4523 aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 ); // defaulting 4524 4525 // clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry 4526 aGeometryItem.ClearPropertyValue( sHandles ); 4527 aGeometryItem.ClearPropertyValue( sEquations ); 4528 aGeometryItem.ClearPropertyValue( sViewBox ); 4529 aGeometryItem.ClearPropertyValue( sPath ); 4530 4531 sal_Int32 nEndAngle = 9000; 4532 sal_Int32 nStartAngle = 0; 4533 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues ); 4534 if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 ) 4535 { 4536 double fNumber; 4537 if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE ) 4538 { 4539 seqAdjustmentValues[ 0 ].Value >>= fNumber; 4540 nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 ); 4541 } 4542 else 4543 { 4544 fNumber = 270.0; 4545 seqAdjustmentValues[ 0 ].Value <<= fNumber; 4546 seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // so this value will properly be stored 4547 } 4548 4549 if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE ) 4550 { 4551 seqAdjustmentValues[ 1 ].Value >>= fNumber; 4552 nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 ); 4553 } 4554 else 4555 { 4556 fNumber = 0.0; 4557 seqAdjustmentValues[ 1 ].Value <<= fNumber; 4558 seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; 4559 } 4560 4561 PropertyValue aPropVal; 4562 aPropVal.Name = sAdjustmentValues; 4563 aPropVal.Value <<= seqAdjustmentValues; 4564 aGeometryItem.SetPropertyValue( aPropVal ); // storing the angle attribute 4565 } 4566 if ( nStartAngle != nEndAngle ) 4567 { 4568 XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2, 4569 (sal_uInt16)nStartAngle / 10, (sal_uInt16)nEndAngle / 10, sal_True ); 4570 Rectangle aPolyPieRect( aXPoly.GetBoundRect() ); 4571 4572 double fYScale, fXScale; 4573 double fYOfs, fXOfs; 4574 4575 Point aP( aObjData.aBoundRect.Center() ); 4576 Size aS( aObjData.aBoundRect.GetSize() ); 4577 aP.X() -= aS.Width() / 2; 4578 aP.Y() -= aS.Height() / 2; 4579 Rectangle aLogicRect( aP, aS ); 4580 4581 fYOfs = fXOfs = 0.0; 4582 4583 if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() ) 4584 { 4585 fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth(); 4586 if ( nSpFlags & SP_FFLIPH ) 4587 fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale; 4588 else 4589 fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale; 4590 } 4591 if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() ) 4592 { 4593 fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight(); 4594 if ( nSpFlags & SP_FFLIPV ) 4595 fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale; 4596 else 4597 fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale; 4598 } 4599 4600 fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth(); 4601 fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight(); 4602 4603 Rectangle aOldBoundRect( aObjData.aBoundRect ); 4604 aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ), 4605 Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) ); 4606 4607 // creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system 4608 double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth(); 4609 double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight(); 4610 sal_Int32 nLeft = (sal_Int32)(( aPolyPieRect.Left() - aPolyBoundRect.Left() ) * fTextFrameScaleX ); 4611 sal_Int32 nTop = (sal_Int32)(( aPolyPieRect.Top() - aPolyBoundRect.Top() ) * fTextFrameScaleY ); 4612 sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX ); 4613 sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() ) * fTextFrameScaleY ); 4614 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 ); 4615 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First, nLeft ); 4616 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second, nTop ); 4617 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight ); 4618 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom ); 4619 PropertyValue aProp; 4620 aProp.Name = sTextFrames; 4621 aProp.Value <<= aTextFrame; 4622 aGeometryItem.SetPropertyValue( sPath, aProp ); 4623 4624 // sj: taking care of the different rotation points, since the new arc is having a bigger snaprect 4625 if ( mnFix16Angle ) 4626 { 4627 sal_Int32 nAngle = mnFix16Angle; 4628 if ( nSpFlags & SP_FFLIPH ) 4629 nAngle = 36000 - nAngle; 4630 if ( nSpFlags & SP_FFLIPV ) 4631 nAngle = -nAngle; 4632 double a = nAngle * F_PI18000; 4633 double ss = sin( a ); 4634 double cc = cos( a ); 4635 Point aP1( aOldBoundRect.TopLeft() ); 4636 Point aC1( aObjData.aBoundRect.Center() ); 4637 Point aP2( aOldBoundRect.TopLeft() ); 4638 Point aC2( aOldBoundRect.Center() ); 4639 RotatePoint( aP1, aC1, ss, cc ); 4640 RotatePoint( aP2, aC2, ss, cc ); 4641 aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() ); 4642 } 4643 } 4644 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem ); 4645 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes(); 4646 4647 // now setting a new name, so the above correction is only done once when importing from ms 4648 SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); 4649 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 4650 const rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) ); 4651 PropertyValue aPropVal; 4652 aPropVal.Name = sType; 4653 aPropVal.Value <<= sName; 4654 aGeoName.SetPropertyValue( aPropVal ); 4655 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName ); 4656 } 4657 else 4658 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes(); 4659 4660 pRet->SetSnapRect( aObjData.aBoundRect ); 4661 EnhancedCustomShape2d aCustomShape2d( pRet ); 4662 aTextRect = aCustomShape2d.GetTextRect(); 4663 4664 bIsCustomShape = sal_True; 4665 4666 if( bIsConnector ) 4667 { 4668 if( nObjectRotation ) 4669 { 4670 double a = nObjectRotation * nPi180; 4671 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) ); 4672 } 4673 // Horizontal gespiegelt? 4674 if ( nSpFlags & SP_FFLIPH ) 4675 { 4676 Rectangle aBndRect( pRet->GetSnapRect() ); 4677 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() ); 4678 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4679 pRet->NbcMirror( aTop, aBottom ); 4680 } 4681 // Vertikal gespiegelt? 4682 if ( nSpFlags & SP_FFLIPV ) 4683 { 4684 Rectangle aBndRect( pRet->GetSnapRect() ); 4685 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 ); 4686 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4687 pRet->NbcMirror( aLeft, aRight ); 4688 } 4689 basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) ); 4690 SdrObject::Free( pRet ); 4691 4692 pRet = new SdrEdgeObj(); 4693 ApplyAttributes( rSt, aSet, aObjData ); 4694 pRet->SetLogicRect( aObjData.aBoundRect ); 4695 pRet->SetMergedItemSet(aSet); 4696 4697 // Konnektoren 4698 MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight ); 4699 4700 ((SdrEdgeObj*)pRet)->ConnectToNode(sal_True, NULL); 4701 ((SdrEdgeObj*)pRet)->ConnectToNode(sal_False, NULL); 4702 4703 Point aPoint1( aObjData.aBoundRect.TopLeft() ); 4704 Point aPoint2( aObjData.aBoundRect.BottomRight() ); 4705 4706 // Rotationen beachten 4707 if ( nObjectRotation ) 4708 { 4709 double a = nObjectRotation * nPi180; 4710 Point aCenter( aObjData.aBoundRect.Center() ); 4711 double ss = sin(a); 4712 double cc = cos(a); 4713 4714 RotatePoint(aPoint1, aCenter, ss, cc); 4715 RotatePoint(aPoint2, aCenter, ss, cc); 4716 } 4717 4718 // Linie innerhalb des Bereiches zurechtdrehen/spiegeln 4719 if ( nSpFlags & SP_FFLIPH ) 4720 { 4721 sal_Int32 n = aPoint1.X(); 4722 aPoint1.X() = aPoint2.X(); 4723 aPoint2.X() = n; 4724 } 4725 if ( nSpFlags & SP_FFLIPV ) 4726 { 4727 sal_Int32 n = aPoint1.Y(); 4728 aPoint1.Y() = aPoint2.Y(); 4729 aPoint2.Y() = n; 4730 } 4731 nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH ); 4732 4733 pRet->NbcSetPoint(aPoint1, 0L); // Startpunkt 4734 pRet->NbcSetPoint(aPoint2, 1L); // Endpunkt 4735 4736 sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist; 4737 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0; 4738 switch( eConnectorStyle ) 4739 { 4740 case mso_cxstyleBent: 4741 { 4742 aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) ); 4743 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630; 4744 } 4745 break; 4746 case mso_cxstyleCurved: 4747 aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) ); 4748 break; 4749 default: // mso_cxstyleStraight || mso_cxstyleNone 4750 aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) ); 4751 break; 4752 } 4753 aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) ); 4754 aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) ); 4755 aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) ); 4756 aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) ); 4757 4758 ((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly ); 4759 pRet->SetMergedItemSet( aSet ); 4760 } 4761 } 4762 } 4763 4764 if ( pRet ) 4765 { 4766 if( nObjectRotation ) 4767 { 4768 double a = nObjectRotation * nPi180; 4769 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) ); 4770 } 4771 // Horizontal gespiegelt? 4772 if ( nSpFlags & SP_FFLIPH ) 4773 { 4774 Rectangle aBndRect( pRet->GetSnapRect() ); 4775 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() ); 4776 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4777 pRet->NbcMirror( aTop, aBottom ); 4778 } 4779 // Vertikal gespiegelt? 4780 if ( nSpFlags & SP_FFLIPV ) 4781 { 4782 Rectangle aBndRect( pRet->GetSnapRect() ); 4783 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 ); 4784 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4785 pRet->NbcMirror( aLeft, aRight ); 4786 } 4787 } 4788 } 4789 } 4790 4791 // #i51348# #118052# name of the shape 4792 if( pRet ) 4793 { 4794 ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt ); 4795 if( aObjName.getLength() > 0 ) 4796 pRet->SetName( aObjName ); 4797 } 4798 4799 pRet = 4800 ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet); 4801 4802 if ( pRet ) 4803 { 4804 sal_Int32 nGroupProperties( GetPropertyValue( DFF_Prop_fPrint ) ); 4805 pRet->SetVisible( ( nGroupProperties & 2 ) == 0 ); 4806 pRet->SetPrintable( ( nGroupProperties & 1 ) != 0 ); 4807 } 4808 4809 if ( mbTracing ) 4810 mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP 4811 ? rtl::OUString::createFromAscii( "GroupShape" ) 4812 : rtl::OUString::createFromAscii( "Shape" ) ); 4813 return pRet; 4814 } 4815 4816 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect ) 4817 { 4818 Rectangle aChildAnchor; 4819 rHd.SeekToContent( rSt ); 4820 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4821 { 4822 DffRecordHeader aShapeHd; 4823 rSt >> aShapeHd; 4824 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || 4825 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) 4826 { 4827 DffRecordHeader aShapeHd2( aShapeHd ); 4828 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) 4829 rSt >> aShapeHd2; 4830 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) ) 4831 { 4832 DffRecordHeader aShapeAtom; 4833 rSt >> aShapeAtom; 4834 4835 if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor ) 4836 { 4837 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT ) 4838 { 4839 sal_Int32 l, t, r, b; 4840 if ( aShapeAtom.nRecLen == 16 ) 4841 { 4842 rSt >> l >> t >> r >> b; 4843 } 4844 else 4845 { 4846 sal_Int16 ls, ts, rs, bs; 4847 rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ... 4848 l = ls, t = ts, r = rs, b = bs; 4849 } 4850 Scale( l ); 4851 Scale( t ); 4852 Scale( r ); 4853 Scale( b ); 4854 aClientRect = Rectangle( l, t, r, b ); 4855 } 4856 break; 4857 } 4858 else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor ) 4859 { 4860 sal_Int32 l, o, r, u; 4861 rSt >> l >> o >> r >> u; 4862 Scale( l ); 4863 Scale( o ); 4864 Scale( r ); 4865 Scale( u ); 4866 Rectangle aChild( l, o, r, u ); 4867 aChildAnchor.Union( aChild ); 4868 break; 4869 } 4870 aShapeAtom.SeekToEndOfRecord( rSt ); 4871 } 4872 } 4873 aShapeHd.SeekToEndOfRecord( rSt ); 4874 } 4875 return aChildAnchor; 4876 } 4877 4878 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt, 4879 Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor, 4880 const Rectangle& rClientRect, const Rectangle& rGlobalChildRect ) 4881 { 4882 sal_Bool bFirst = sal_True; 4883 rHd.SeekToContent( rSt ); 4884 DffRecordHeader aShapeHd; 4885 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4886 { 4887 rSt >> aShapeHd; 4888 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || 4889 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) 4890 { 4891 DffRecordHeader aShapeHd2( aShapeHd ); 4892 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) 4893 rSt >> aShapeHd2; 4894 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) ) 4895 { 4896 DffRecordHeader aShapeAtom; 4897 rSt >> aShapeAtom; 4898 if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor ) 4899 { 4900 sal_Int32 l, o, r, u; 4901 rSt >> l >> o >> r >> u; 4902 Scale( l ); 4903 Scale( o ); 4904 Scale( r ); 4905 Scale( u ); 4906 Rectangle aChild( l, o, r, u ); 4907 4908 if ( bFirst ) 4909 { 4910 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() ) 4911 { 4912 double fl = l; 4913 double fo = o; 4914 double fWidth = r - l; 4915 double fHeight= u - o; 4916 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth(); 4917 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight(); 4918 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left(); 4919 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top(); 4920 fWidth *= fXScale; 4921 fHeight *= fYScale; 4922 rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) ); 4923 } 4924 bFirst = sal_False; 4925 } 4926 else 4927 rGroupChildAnchor.Union( aChild ); 4928 break; 4929 } 4930 aShapeAtom.SeekToEndOfRecord( rSt ); 4931 } 4932 } 4933 aShapeHd.SeekToEndOfRecord( rSt ); 4934 } 4935 } 4936 4937 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt, 4938 DffObjData& rObjData, 4939 void* pData, 4940 Rectangle& rTextRect, 4941 SdrObject* pObj 4942 ) 4943 { 4944 if( !rTextRect.IsEmpty() ) 4945 { 4946 SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData; 4947 SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec; 4948 SvxMSDffImportRec* pTextImpRec = pImpRec; 4949 4950 // fill Import Record with data 4951 pImpRec->nShapeId = rObjData.nShapeId; 4952 pImpRec->eShapeType = rObjData.eShapeType; 4953 4954 MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue( 4955 DFF_Prop_WrapText, 4956 mso_wrapSquare ) ); 4957 rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, 4958 DFF_msofbtClientAnchor, 4959 SEEK_FROM_CURRENT_AND_RESTART ); 4960 if( rObjData.bClientAnchor ) 4961 ProcessClientAnchor( rSt, 4962 maShapeRecords.Current()->nRecLen, 4963 pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen ); 4964 4965 rObjData.bClientData = maShapeRecords.SeekToContent( rSt, 4966 DFF_msofbtClientData, 4967 SEEK_FROM_CURRENT_AND_RESTART ); 4968 if( rObjData.bClientData ) 4969 ProcessClientData( rSt, 4970 maShapeRecords.Current()->nRecLen, 4971 pImpRec->pClientDataBuffer, pImpRec->nClientDataLen ); 4972 4973 4974 // process user (== Winword) defined parameters in 0xF122 record 4975 if( maShapeRecords.SeekToContent( rSt, 4976 DFF_msofbtUDefProp, 4977 SEEK_FROM_CURRENT_AND_RESTART ) 4978 && maShapeRecords.Current()->nRecLen ) 4979 { 4980 sal_uInt32 nBytesLeft = maShapeRecords.Current()->nRecLen; 4981 sal_uInt32 nUDData; 4982 sal_uInt16 nPID; 4983 while( 5 < nBytesLeft ) 4984 { 4985 rSt >> nPID; 4986 if ( rSt.GetError() != 0 ) 4987 break; 4988 rSt >> nUDData; 4989 switch( nPID ) 4990 { 4991 case 0x038F: pImpRec->nXAlign = nUDData; break; 4992 case 0x0390: pImpRec->nXRelTo = nUDData; break; 4993 case 0x0391: pImpRec->nYAlign = nUDData; break; 4994 case 0x0392: pImpRec->nYRelTo = nUDData; break; 4995 case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break; 4996 } 4997 if ( rSt.GetError() != 0 ) 4998 break; 4999 pImpRec->bHasUDefProp = sal_True; 5000 nBytesLeft -= 6; 5001 } 5002 } 5003 5004 // Textrahmen, auch Title oder Outline 5005 SdrObject* pOrgObj = pObj; 5006 SdrRectObj* pTextObj = 0; 5007 sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 ); 5008 if( nTextId ) 5009 { 5010 SfxItemSet aSet( pSdrModel->GetItemPool() ); 5011 5012 //Originally anything that as a mso_sptTextBox was created as a 5013 //textbox, this was changed for #88277# to be created as a simple 5014 //rect to keep impress happy. For the rest of us we'd like to turn 5015 //it back into a textbox again. 5016 FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox); 5017 if (!bTextFrame) 5018 { 5019 //Either 5020 //a) its a simple text object or 5021 //b) its a rectangle with text and square wrapping. 5022 bTextFrame = 5023 ( 5024 (pImpRec->eShapeType == mso_sptTextSimple) || 5025 ( 5026 (pImpRec->eShapeType == mso_sptRectangle) 5027 && (eWrapMode == mso_wrapSquare) 5028 && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() ) 5029 ) 5030 ); 5031 } 5032 5033 if (bTextFrame) 5034 { 5035 SdrObject::Free( pObj ); 5036 pObj = pOrgObj = 0; 5037 } 5038 5039 // Distance of Textbox to it's surrounding Customshape 5040 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L); 5041 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L ); 5042 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L ); 5043 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L ); 5044 5045 ScaleEmu( nTextLeft ); 5046 ScaleEmu( nTextRight ); 5047 ScaleEmu( nTextTop ); 5048 ScaleEmu( nTextBottom ); 5049 5050 sal_Int32 nTextRotationAngle=0; 5051 bool bVerticalText = false; 5052 if ( IsProperty( DFF_Prop_txflTextFlow ) ) 5053 { 5054 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue( 5055 DFF_Prop_txflTextFlow) & 0xFFFF); 5056 switch( eTextFlow ) 5057 { 5058 case mso_txflBtoT: 5059 nTextRotationAngle = 9000; 5060 break; 5061 case mso_txflVertN: 5062 case mso_txflTtoBN: 5063 nTextRotationAngle = 27000; 5064 break; 5065 case mso_txflTtoBA: 5066 bVerticalText = true; 5067 break; 5068 case mso_txflHorzA: 5069 bVerticalText = true; 5070 nTextRotationAngle = 9000; 5071 case mso_txflHorzN: 5072 default : 5073 break; 5074 } 5075 } 5076 5077 if (nTextRotationAngle) 5078 { 5079 while (nTextRotationAngle > 360000) 5080 nTextRotationAngle-=9000; 5081 switch (nTextRotationAngle) 5082 { 5083 case 9000: 5084 { 5085 long nWidth = rTextRect.GetWidth(); 5086 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight(); 5087 rTextRect.Bottom() = rTextRect.Top() + nWidth; 5088 5089 sal_Int32 nOldTextLeft = nTextLeft; 5090 sal_Int32 nOldTextRight = nTextRight; 5091 sal_Int32 nOldTextTop = nTextTop; 5092 sal_Int32 nOldTextBottom = nTextBottom; 5093 5094 nTextLeft = nOldTextBottom; 5095 nTextRight = nOldTextTop; 5096 nTextTop = nOldTextLeft; 5097 nTextBottom = nOldTextRight; 5098 } 5099 break; 5100 case 27000: 5101 { 5102 long nWidth = rTextRect.GetWidth(); 5103 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight(); 5104 rTextRect.Bottom() = rTextRect.Top() + nWidth; 5105 5106 sal_Int32 nOldTextLeft = nTextLeft; 5107 sal_Int32 nOldTextRight = nTextRight; 5108 sal_Int32 nOldTextTop = nTextTop; 5109 sal_Int32 nOldTextBottom = nTextBottom; 5110 5111 nTextLeft = nOldTextTop; 5112 nTextRight = nOldTextBottom; 5113 nTextTop = nOldTextRight; 5114 nTextBottom = nOldTextLeft; 5115 } 5116 break; 5117 default: 5118 break; 5119 } 5120 } 5121 5122 pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect); 5123 pTextImpRec = new SvxMSDffImportRec(*pImpRec); 5124 5125 // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin, 5126 // hier rausrechnen 5127 Rectangle aNewRect(rTextRect); 5128 aNewRect.Bottom() -= nTextTop + nTextBottom; 5129 aNewRect.Right() -= nTextLeft + nTextRight; 5130 5131 // Nur falls es eine einfache Textbox ist, darf der Writer 5132 // das Objekt durch einen Rahmen ersetzen, ansonsten 5133 if( bTextFrame ) 5134 { 5135 SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId ); 5136 aTmpRec.bSortByShapeId = sal_True; 5137 5138 sal_uInt16 nFound; 5139 if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) ) 5140 { 5141 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound); 5142 pTextImpRec->bReplaceByFly = rInfo.bReplaceByFly; 5143 pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain; 5144 } 5145 } 5146 5147 if( !pObj ) 5148 ApplyAttributes( rSt, aSet, rObjData ); 5149 5150 bool bFitText = false; 5151 if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2) 5152 { 5153 aSet.Put( SdrTextAutoGrowHeightItem( sal_True ) ); 5154 aSet.Put( SdrTextMinFrameHeightItem( 5155 aNewRect.Bottom() - aNewRect.Top() ) ); 5156 aSet.Put( SdrTextMinFrameWidthItem( 5157 aNewRect.Right() - aNewRect.Left() ) ); 5158 bFitText = true; 5159 } 5160 else 5161 { 5162 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) ); 5163 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) ); 5164 } 5165 5166 switch ( (MSO_WrapMode) 5167 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) ) 5168 { 5169 case mso_wrapNone : 5170 aSet.Put( SdrTextAutoGrowWidthItem( sal_True ) ); 5171 if (bFitText) 5172 { 5173 //can't do autowidth in flys #i107184# 5174 pTextImpRec->bReplaceByFly = false; 5175 } 5176 break; 5177 case mso_wrapByPoints : 5178 aSet.Put( SdrTextContourFrameItem( sal_True ) ); 5179 break; 5180 default: break; 5181 } 5182 5183 // Abstaende an den Raendern der Textbox setzen 5184 aSet.Put( SdrTextLeftDistItem( nTextLeft ) ); 5185 aSet.Put( SdrTextRightDistItem( nTextRight ) ); 5186 aSet.Put( SdrTextUpperDistItem( nTextTop ) ); 5187 aSet.Put( SdrTextLowerDistItem( nTextBottom ) ); 5188 pTextImpRec->nDxTextLeft = nTextLeft; 5189 pTextImpRec->nDyTextTop = nTextTop; 5190 pTextImpRec->nDxTextRight = nTextRight; 5191 pTextImpRec->nDyTextBottom = nTextBottom; 5192 5193 // Textverankerung lesen 5194 if ( IsProperty( DFF_Prop_anchorText ) ) 5195 { 5196 MSO_Anchor eTextAnchor = 5197 (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText ); 5198 5199 SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER; 5200 sal_Bool bTVASet(sal_False); 5201 SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER; 5202 sal_Bool bTHASet(sal_False); 5203 5204 switch( eTextAnchor ) 5205 { 5206 case mso_anchorTop: 5207 { 5208 eTVA = SDRTEXTVERTADJUST_TOP; 5209 bTVASet = sal_True; 5210 } 5211 break; 5212 case mso_anchorTopCentered: 5213 { 5214 eTVA = SDRTEXTVERTADJUST_TOP; 5215 bTVASet = sal_True; 5216 bTHASet = sal_True; 5217 } 5218 break; 5219 5220 case mso_anchorMiddle: 5221 bTVASet = sal_True; 5222 break; 5223 case mso_anchorMiddleCentered: 5224 { 5225 bTVASet = sal_True; 5226 bTHASet = sal_True; 5227 } 5228 break; 5229 case mso_anchorBottom: 5230 { 5231 eTVA = SDRTEXTVERTADJUST_BOTTOM; 5232 bTVASet = sal_True; 5233 } 5234 break; 5235 case mso_anchorBottomCentered: 5236 { 5237 eTVA = SDRTEXTVERTADJUST_BOTTOM; 5238 bTVASet = sal_True; 5239 bTHASet = sal_True; 5240 } 5241 break; 5242 /* 5243 case mso_anchorTopBaseline: 5244 case mso_anchorBottomBaseline: 5245 case mso_anchorTopCenteredBaseline: 5246 case mso_anchorBottomCenteredBaseline: 5247 break; 5248 */ 5249 default : break; 5250 } 5251 // Einsetzen 5252 if ( bTVASet ) 5253 aSet.Put( SdrTextVertAdjustItem( eTVA ) ); 5254 if ( bTHASet ) 5255 aSet.Put( SdrTextHorzAdjustItem( eTHA ) ); 5256 } 5257 5258 pTextObj->SetMergedItemSet(aSet); 5259 pTextObj->SetModel(pSdrModel); 5260 5261 if (bVerticalText) 5262 pTextObj->SetVerticalWriting(sal_True); 5263 5264 if (nTextRotationAngle) 5265 { 5266 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ? 5267 rTextRect.GetWidth() : rTextRect.GetHeight(); 5268 nMinWH /= 2; 5269 Point aPivot(rTextRect.TopLeft()); 5270 aPivot.X() += nMinWH; 5271 aPivot.Y() += nMinWH; 5272 double a = nTextRotationAngle * nPi180; 5273 pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a)); 5274 } 5275 5276 // rotate text with shape ? 5277 if ( mnFix16Angle ) 5278 { 5279 double a = mnFix16Angle * nPi180; 5280 pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle, 5281 sin( a ), cos( a ) ); 5282 } 5283 5284 if( !pObj ) 5285 { 5286 pObj = pTextObj; 5287 } 5288 else 5289 { 5290 if( pTextObj != pObj ) 5291 { 5292 SdrObject* pGroup = new SdrObjGroup; 5293 pGroup->GetSubList()->NbcInsertObject( pObj ); 5294 pGroup->GetSubList()->NbcInsertObject( pTextObj ); 5295 if (pOrgObj == pObj) 5296 pOrgObj = pGroup; 5297 else 5298 pOrgObj = pObj; 5299 pObj = pGroup; 5300 } 5301 } 5302 } 5303 else if( !pObj ) 5304 { 5305 // simple rectangular objects are ignored by ImportObj() :-( 5306 // this is OK for Draw but not for Calc and Writer 5307 // cause here these objects have a default border 5308 pObj = new SdrRectObj(rTextRect); 5309 pOrgObj = pObj; 5310 pObj->SetModel( pSdrModel ); 5311 SfxItemSet aSet( pSdrModel->GetItemPool() ); 5312 ApplyAttributes( rSt, aSet, rObjData ); 5313 5314 const SfxPoolItem* pPoolItem=NULL; 5315 SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR, 5316 sal_False, &pPoolItem ); 5317 if( SFX_ITEM_DEFAULT == eState ) 5318 aSet.Put( XFillColorItem( String(), 5319 Color( mnDefaultColor ) ) ); 5320 pObj->SetMergedItemSet(aSet); 5321 } 5322 5323 //Means that fBehindDocument is set 5324 if (GetPropertyValue(DFF_Prop_fPrint) & 0x20) 5325 pImpRec->bDrawHell = sal_True; 5326 else 5327 pImpRec->bDrawHell = sal_False; 5328 if (GetPropertyValue(DFF_Prop_fPrint) & 0x02) 5329 pImpRec->bHidden = sal_True; 5330 pTextImpRec->bDrawHell = pImpRec->bDrawHell; 5331 pTextImpRec->bHidden = pImpRec->bHidden; 5332 pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 ); 5333 pTextImpRec->nNextShapeId=pImpRec->nNextShapeId; 5334 5335 if ( nTextId ) 5336 { 5337 pTextImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 ); 5338 pTextImpRec->aTextId.nSequence = (sal_uInt16)nTextId; 5339 } 5340 5341 pTextImpRec->nDxWrapDistLeft = GetPropertyValue( 5342 DFF_Prop_dxWrapDistLeft, 114935L ) / 635L; 5343 pTextImpRec->nDyWrapDistTop = GetPropertyValue( 5344 DFF_Prop_dyWrapDistTop, 0 ) / 635L; 5345 pTextImpRec->nDxWrapDistRight = GetPropertyValue( 5346 DFF_Prop_dxWrapDistRight, 114935L ) / 635L; 5347 pTextImpRec->nDyWrapDistBottom = GetPropertyValue( 5348 DFF_Prop_dyWrapDistBottom, 0 ) / 635L; 5349 // 16.16 fraction times total image width or height, as appropriate. 5350 5351 if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt)) 5352 { 5353 delete pTextImpRec->pWrapPolygon; 5354 sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert; 5355 rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert; 5356 if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4))) 5357 { 5358 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert); 5359 for (sal_uInt16 i = 0; i < nNumElemVert; ++i) 5360 { 5361 sal_Int32 nX, nY; 5362 if (nElemSizeVert == 8) 5363 rSt >> nX >> nY; 5364 else 5365 { 5366 sal_Int16 nSmallX, nSmallY; 5367 rSt >> nSmallX >> nSmallY; 5368 nX = nSmallX; 5369 nY = nSmallY; 5370 } 5371 (*(pTextImpRec->pWrapPolygon))[i].X() = nX; 5372 (*(pTextImpRec->pWrapPolygon))[i].Y() = nY; 5373 } 5374 } 5375 } 5376 5377 pImpRec->nCropFromTop = GetPropertyValue( 5378 DFF_Prop_cropFromTop, 0 ); 5379 pImpRec->nCropFromBottom = GetPropertyValue( 5380 DFF_Prop_cropFromBottom, 0 ); 5381 pImpRec->nCropFromLeft = GetPropertyValue( 5382 DFF_Prop_cropFromLeft, 0 ); 5383 pImpRec->nCropFromRight = GetPropertyValue( 5384 DFF_Prop_cropFromRight, 0 ); 5385 5386 pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false; 5387 pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false; 5388 5389 sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash ); 5390 pImpRec->eLineStyle = (nLineFlags & 8) 5391 ? (MSO_LineStyle)GetPropertyValue( 5392 DFF_Prop_lineStyle, 5393 mso_lineSimple ) 5394 : (MSO_LineStyle)USHRT_MAX; 5395 pTextImpRec->eLineStyle = pImpRec->eLineStyle; 5396 5397 if( pImpRec->nShapeId ) 5398 { 5399 // Import-Record-Liste ergaenzen 5400 if( pOrgObj ) 5401 { 5402 pImpRec->pObj = pOrgObj; 5403 rImportData.aRecords.Insert( pImpRec ); 5404 } 5405 5406 if( pTextObj && (pOrgObj != pTextObj) ) 5407 { 5408 // Modify ShapeId (must be unique) 5409 pImpRec->nShapeId |= 0x8000000; 5410 pTextImpRec->pObj = pTextObj; 5411 rImportData.aRecords.Insert( pTextImpRec ); 5412 } 5413 5414 // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen 5415 /*Only store objects which are not deep inside the tree*/ 5416 if( ( rObjData.nCalledByGroup == 0 ) 5417 || 5418 ( (rObjData.nSpFlags & SP_FGROUP) 5419 && (rObjData.nCalledByGroup < 2) ) 5420 ) 5421 StoreShapeOrder( pImpRec->nShapeId, 5422 ( ( (sal_uLong)pImpRec->aTextId.nTxBxS ) << 16 ) 5423 + pImpRec->aTextId.nSequence, pObj ); 5424 } 5425 else 5426 delete pImpRec; 5427 } 5428 5429 return pObj; 5430 }; 5431 5432 void SvxMSDffManager::StoreShapeOrder(sal_uLong nId, 5433 sal_uLong nTxBx, 5434 SdrObject* pObject, 5435 SwFlyFrmFmt* pFly, 5436 short nHdFtSection) const 5437 { 5438 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5439 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5440 { 5441 SvxMSDffShapeOrder& rOrder 5442 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5443 5444 if( rOrder.nShapeId == nId ) 5445 { 5446 rOrder.nTxBxComp = nTxBx; 5447 rOrder.pObj = pObject; 5448 rOrder.pFly = pFly; 5449 rOrder.nHdFtSection = nHdFtSection; 5450 } 5451 } 5452 } 5453 5454 5455 void SvxMSDffManager::ExchangeInShapeOrder( SdrObject* pOldObject, 5456 sal_uLong nTxBx, 5457 SwFlyFrmFmt* pFly, 5458 SdrObject* pObject) const 5459 { 5460 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5461 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5462 { 5463 SvxMSDffShapeOrder& rOrder 5464 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5465 5466 if( rOrder.pObj == pOldObject ) 5467 { 5468 rOrder.pFly = pFly; 5469 rOrder.pObj = pObject; 5470 rOrder.nTxBxComp = nTxBx; 5471 } 5472 } 5473 } 5474 5475 5476 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const 5477 { 5478 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5479 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5480 { 5481 SvxMSDffShapeOrder& rOrder 5482 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5483 5484 if( rOrder.pObj == pObject ) 5485 { 5486 rOrder.pObj = 0; 5487 rOrder.pFly = 0; 5488 rOrder.nTxBxComp = 0; 5489 } 5490 } 5491 } 5492 5493 5494 5495 5496 //--------------------------------------------------------------------------- 5497 // Hilfs Deklarationen 5498 //--------------------------------------------------------------------------- 5499 5500 /*struct SvxMSDffBLIPInfo -> in's Header-File 5501 { 5502 sal_uInt16 nBLIPType; // Art des BLIP: z.B. 6 fuer PNG 5503 sal_uLong nFilePos; // Offset des BLIP im Daten-Stream 5504 sal_uLong nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt 5505 SvxMSDffBLIPInfo(sal_uInt16 nBType, sal_uLong nFPos, sal_uLong nBSize): 5506 nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){} 5507 }; 5508 */ 5509 5510 SV_IMPL_PTRARR( SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr ); 5511 5512 SV_IMPL_PTRARR( SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr ); 5513 5514 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr ); 5515 5516 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr ); 5517 5518 5519 // Liste aller SvxMSDffImportRec fuer eine Gruppe 5520 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr) 5521 5522 //--------------------------------------------------------------------------- 5523 // exportierte Klasse: oeffentliche Methoden 5524 //--------------------------------------------------------------------------- 5525 5526 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_, 5527 const String& rBaseURL, 5528 long nOffsDgg_, 5529 SvStream* pStData_, 5530 SdrModel* pSdrModel_,// s. unten: SetModel() 5531 long nApplicationScale, 5532 ColorData mnDefaultColor_, 5533 sal_uLong nDefaultFontHeight_, 5534 SvStream* pStData2_, 5535 MSFilterTracer* pTracer ) 5536 :DffPropertyReader( *this ), 5537 pFormModel( NULL ), 5538 pBLIPInfos( new SvxMSDffBLIPInfos ), 5539 pShapeInfos( new SvxMSDffShapeInfos ), 5540 pShapeOrders( new SvxMSDffShapeOrders ), 5541 nDefaultFontHeight( nDefaultFontHeight_), 5542 nOffsDgg( nOffsDgg_ ), 5543 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen, 5544 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt 5545 maBaseURL( rBaseURL ), 5546 mpFidcls( NULL ), 5547 rStCtrl( rStCtrl_ ), 5548 pStData( pStData_ ), 5549 pStData2( pStData2_ ), 5550 nSvxMSDffSettings( 0 ), 5551 nSvxMSDffOLEConvFlags( 0 ), 5552 pSecPropSet( NULL ), 5553 pEscherBlipCache( NULL ), 5554 mnDefaultColor( mnDefaultColor_), 5555 mpTracer( pTracer ), 5556 mbTracing( sal_False ) 5557 { 5558 if ( mpTracer ) 5559 { 5560 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) ); 5561 aAny >>= mbTracing; 5562 } 5563 SetModel( pSdrModel_, nApplicationScale ); 5564 5565 // FilePos des/der Stream(s) merken 5566 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 5567 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 5568 5569 // Falls kein Datenstream angegeben, gehen wir davon aus, 5570 // dass die BLIPs im Steuerstream stehen. 5571 if( !pStData ) 5572 pStData = &rStCtrl; 5573 5574 SetDefaultPropSet( rStCtrl, nOffsDgg ); 5575 5576 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen 5577 GetCtrlData( nOffsDgg ); 5578 5579 // Text-Box-Story-Ketten-Infos ueberpruefen 5580 CheckTxBxStoryChain(); 5581 5582 // alte FilePos des/der Stream(s) restaurieren 5583 rStCtrl.Seek( nOldPosCtrl ); 5584 if( &rStCtrl != pStData ) 5585 pStData->Seek( nOldPosData ); 5586 } 5587 5588 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer ) 5589 :DffPropertyReader( *this ), 5590 pFormModel( NULL ), 5591 pBLIPInfos( new SvxMSDffBLIPInfos ), 5592 pShapeInfos( new SvxMSDffShapeInfos ), 5593 pShapeOrders( new SvxMSDffShapeOrders ), 5594 nDefaultFontHeight( 24 ), 5595 nOffsDgg( 0 ), 5596 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen, 5597 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt 5598 maBaseURL( rBaseURL ), 5599 mpFidcls( NULL ), 5600 rStCtrl( rStCtrl_ ), 5601 pStData( 0 ), 5602 pStData2( 0 ), 5603 nSvxMSDffSettings( 0 ), 5604 nSvxMSDffOLEConvFlags( 0 ), 5605 pSecPropSet( NULL ), 5606 pEscherBlipCache( NULL ), 5607 mnDefaultColor( COL_DEFAULT ), 5608 mpTracer( pTracer ), 5609 mbTracing( sal_False ) 5610 { 5611 if ( mpTracer ) 5612 { 5613 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) ); 5614 aAny >>= mbTracing; 5615 } 5616 SetModel( NULL, 0 ); 5617 } 5618 5619 SvxMSDffManager::~SvxMSDffManager() 5620 { 5621 if ( pEscherBlipCache ) 5622 { 5623 void* pPtr; 5624 for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() ) 5625 delete (EscherBlipCacheEntry*)pPtr; 5626 delete pEscherBlipCache; 5627 } 5628 delete pSecPropSet; 5629 delete pBLIPInfos; 5630 delete pShapeInfos; 5631 delete pShapeOrders; 5632 delete pFormModel; 5633 delete[] mpFidcls; 5634 } 5635 5636 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags ) 5637 { 5638 nOffsDgg = nOffsDgg_; 5639 pStData = pStData_; 5640 nSvxMSDffOLEConvFlags = nOleConvFlags; 5641 5642 // FilePos des/der Stream(s) merken 5643 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 5644 5645 SetDefaultPropSet( rStCtrl, nOffsDgg ); 5646 5647 // insert fidcl cluster table 5648 GetFidclData( nOffsDgg ); 5649 5650 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen 5651 GetCtrlData( nOffsDgg ); 5652 5653 // Text-Box-Story-Ketten-Infos ueberpruefen 5654 CheckTxBxStoryChain(); 5655 5656 // alte FilePos des/der Stream(s) restaurieren 5657 rStCtrl.Seek( nOldPosCtrl ); 5658 } 5659 5660 void SvxMSDffManager::SetDgContainer( SvStream& rSt ) 5661 { 5662 sal_uInt32 nFilePos = rSt.Tell(); 5663 DffRecordHeader aDgContHd; 5664 rSt >> aDgContHd; 5665 // insert this container only if there is also a DgAtom 5666 if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) ) 5667 { 5668 DffRecordHeader aRecHd; 5669 rSt >> aRecHd; 5670 sal_uInt32 nDrawingId = aRecHd.nRecInstance; 5671 maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos ); 5672 rSt.Seek( nFilePos ); 5673 } 5674 } 5675 5676 void SvxMSDffManager::GetFidclData( long nOffsDggL ) 5677 { 5678 if ( nOffsDggL ) 5679 { 5680 sal_uInt32 nDummy, nMerk = rStCtrl.Tell(); 5681 rStCtrl.Seek( nOffsDggL ); 5682 5683 DffRecordHeader aRecHd; 5684 rStCtrl >> aRecHd; 5685 5686 DffRecordHeader aDggAtomHd; 5687 if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) ) 5688 { 5689 aDggAtomHd.SeekToContent( rStCtrl ); 5690 rStCtrl >> mnCurMaxShapeId 5691 >> mnIdClusters 5692 >> nDummy 5693 >> mnDrawingsSaved; 5694 5695 if ( mnIdClusters-- > 2 ) 5696 { 5697 if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) ) 5698 { 5699 //mpFidcls = new FIDCL[ mnIdClusters ]; 5700 mpFidcls = new (std::nothrow) FIDCL[ mnIdClusters ]; 5701 if ( mpFidcls ) { 5702 for ( sal_uInt32 i = 0; i < mnIdClusters; i++ ) 5703 { 5704 rStCtrl >> mpFidcls[ i ].dgid 5705 >> mpFidcls[ i ].cspidCur; 5706 } 5707 } 5708 } 5709 } 5710 } 5711 rStCtrl.Seek( nMerk ); 5712 } 5713 } 5714 5715 void SvxMSDffManager::CheckTxBxStoryChain() 5716 { 5717 SvxMSDffShapeInfos* pOld = pShapeInfos; 5718 sal_uInt16 nCnt = pOld->Count(); 5719 pShapeInfos = new SvxMSDffShapeInfos( (nCnt < 255) 5720 ? nCnt 5721 : 255 ); 5722 // altes Info-Array ueberarbeiten 5723 // (ist sortiert nach nTxBxComp) 5724 sal_uLong nChain = ULONG_MAX; 5725 sal_uInt16 nObjMark = 0; 5726 sal_Bool bSetReplaceFALSE = sal_False; 5727 sal_uInt16 nObj; 5728 for( nObj = 0; nObj < nCnt; ++nObj ) 5729 { 5730 SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj ); 5731 if( pObj->nTxBxComp ) 5732 { 5733 pObj->bLastBoxInChain = sal_False; 5734 // Gruppenwechsel ? 5735 // --> OD 2008-07-28 #156763# 5736 // the text id also contains an internal drawing container id 5737 // to distinguish between text id of drawing objects in different 5738 // drawing containers. 5739 // if( nChain != (pObj->nTxBxComp & 0xFFFF0000) ) 5740 if( nChain != pObj->nTxBxComp ) 5741 // <-- 5742 { 5743 // voriger war letzter seiner Gruppe 5744 if( nObj ) 5745 pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True; 5746 // Merker und Hilfs-Flag zuruecksetzen 5747 nObjMark = nObj; 5748 // --> OD 2008-07-28 #156763# 5749 // nChain = pObj->nTxBxComp & 0xFFFF0000; 5750 nChain = pObj->nTxBxComp; 5751 // <-- 5752 bSetReplaceFALSE = !pObj->bReplaceByFly; 5753 } 5754 else 5755 if( !pObj->bReplaceByFly ) 5756 { 5757 // Objekt, das NICHT durch Rahmen ersetzt werden darf ? 5758 // Hilfs-Flag setzen 5759 bSetReplaceFALSE = sal_True; 5760 // ggfs Flag in Anfang der Gruppe austragen 5761 for( sal_uInt16 nObj2 = nObjMark; nObj2 < nObj; ++nObj2 ) 5762 pOld->GetObject( nObj2 )->bReplaceByFly = sal_False; 5763 } 5764 5765 if( bSetReplaceFALSE ) 5766 { 5767 pObj->bReplaceByFly = sal_False; 5768 } 5769 } 5770 // alle Shape-Info-Objekte in pShapeInfos umkopieren 5771 // (aber nach nShapeId sortieren) 5772 pObj->bSortByShapeId = sal_True; 5773 // --> OD 2008-07-28 #156763# 5774 pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000; 5775 // <-- 5776 pShapeInfos->Insert( pObj ); 5777 } 5778 // voriger war letzter seiner Gruppe 5779 if( nObj ) 5780 pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True; 5781 // urspruengliches Array freigeben, ohne Objekte zu zerstoeren 5782 pOld->Remove((sal_uInt16)0, nCnt); 5783 delete pOld; 5784 } 5785 5786 5787 /***************************************************************************** 5788 5789 Einlesen der Shape-Infos im Ctor: 5790 --------------------------------- 5791 merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos 5792 ========= ============ ============= 5793 und merken des File-Offsets fuer jedes Blip 5794 ============ 5795 ******************************************************************************/ 5796 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ ) 5797 { 5798 // Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen 5799 long nOffsDggL = nOffsDgg_; 5800 5801 // Kontroll Stream positionieren 5802 rStCtrl.Seek( nOffsDggL ); 5803 5804 sal_uInt8 nVer; 5805 sal_uInt16 nInst; 5806 sal_uInt16 nFbt; 5807 sal_uInt32 nLength; 5808 if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return; 5809 5810 sal_Bool bOk; 5811 sal_uLong nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE; 5812 5813 // Fall A: erst Drawing Group Container, dann n Mal Drawing Container 5814 if( DFF_msofbtDggContainer == nFbt ) 5815 { 5816 GetDrawingGroupContainerData( rStCtrl, nLength ); 5817 5818 rStCtrl.Seek( STREAM_SEEK_TO_END ); 5819 sal_uInt32 nMaxStrPos = rStCtrl.Tell(); 5820 5821 nPos += nLength; 5822 // --> OD 2008-07-28 #156763# 5823 unsigned long nDrawingContainerId = 1; 5824 // <-- 5825 do 5826 { 5827 rStCtrl.Seek( nPos ); 5828 5829 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt ); 5830 5831 if( !bOk ) 5832 { 5833 nPos++; // ????????? TODO: trying to get an one-hit wonder, this code code should be rewritten... 5834 rStCtrl.Seek( nPos ); 5835 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) 5836 && ( DFF_msofbtDgContainer == nFbt ); 5837 } 5838 if( bOk ) 5839 { 5840 // --> OD 2008-07-28 #156763# 5841 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId ); 5842 // <-- 5843 } 5844 nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5845 // --> OD 2008-07-28 #156763# 5846 ++nDrawingContainerId; 5847 // <-- 5848 } 5849 while( ( rStCtrl.GetError() == 0 ) && ( nPos < nMaxStrPos ) && bOk ); 5850 } 5851 } 5852 5853 5854 // ab hier: Drawing Group Container d.h. Dokument - weit gueltige Daten 5855 // ======================= ======== 5856 // 5857 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, sal_uLong nLenDgg ) 5858 { 5859 sal_uInt8 nVer; 5860 sal_uInt16 nInst; 5861 sal_uInt16 nFbt; 5862 sal_uInt32 nLength; 5863 5864 sal_uLong nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0; 5865 5866 // Nach einem BStore Container suchen 5867 do 5868 { 5869 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5870 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5871 if( DFF_msofbtBstoreContainer == nFbt ) 5872 { 5873 nLenBStoreCont = nLength; break; 5874 } 5875 rSt.SeekRel( nLength ); 5876 } 5877 while( nRead < nLenDgg ); 5878 5879 if( !nLenBStoreCont ) return; 5880 5881 // Im BStore Container alle Header der Container und Atome auslesen und die 5882 // relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen. 5883 // Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit. 5884 5885 const sal_uLong nSkipBLIPLen = 20; // bis zu nBLIPLen zu ueberspringende Bytes 5886 const sal_uLong nSkipBLIPPos = 4; // dahinter bis zu nBLIPPos zu skippen 5887 5888 sal_uInt32 nBLIPLen = 0, nBLIPPos = 0; 5889 5890 nRead = 0; 5891 do 5892 { 5893 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5894 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5895 if( DFF_msofbtBSE == nFbt ) 5896 { 5897 nLenFBSE = nLength; 5898 // ist FBSE gross genug fuer unsere Daten 5899 sal_Bool bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE ); 5900 5901 if( bOk ) 5902 { 5903 rSt.SeekRel( nSkipBLIPLen ); 5904 rSt >> nBLIPLen; 5905 rSt.SeekRel( nSkipBLIPPos ); 5906 rSt >> nBLIPPos; 5907 bOk = rSt.GetError() == 0; 5908 5909 nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4; 5910 } 5911 5912 if( bOk ) 5913 { 5914 // Besonderheit: 5915 // Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist, 5916 // nehmen wir an, dass das Bild IM FBSE drin steht! 5917 if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) ) 5918 nBLIPPos = rSt.Tell() + 4; 5919 5920 // Das hat ja fein geklappt! 5921 // Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben. 5922 nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell()); 5923 5924 if( USHRT_MAX == nBLIPCount ) 5925 nBLIPCount = 1; 5926 else 5927 nBLIPCount++; 5928 5929 // Jetzt die Infos fuer spaetere Zugriffe speichern 5930 pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ), 5931 pBLIPInfos->Count() ); 5932 } 5933 } 5934 rSt.SeekRel( nLength ); 5935 } 5936 while( nRead < nLenBStoreCont ); 5937 } 5938 5939 5940 // ab hier: Drawing Container d.h. Seiten (Blatt, Dia) - weit gueltige Daten 5941 // ================= ====== 5942 // 5943 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, sal_uLong nLenDg, 5944 const unsigned long nDrawingContainerId ) 5945 { 5946 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 5947 5948 sal_uLong nReadDg = 0; 5949 5950 // Wir stehen in einem Drawing Container (je einer pro Seite) 5951 // und muessen nun 5952 // alle enthaltenen Shape Group Container abklappern 5953 do 5954 { 5955 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5956 nReadDg += DFF_COMMON_RECORD_HEADER_SIZE; 5957 // Patriarch gefunden (der oberste Shape Group Container) ? 5958 if( DFF_msofbtSpgrContainer == nFbt ) 5959 { 5960 if(!this->GetShapeGroupContainerData( rSt, nLength, sal_True, nDrawingContainerId )) return; 5961 } 5962 else 5963 // blanker Shape Container ? (ausserhalb vom Shape Group Container) 5964 if( DFF_msofbtSpContainer == nFbt ) 5965 { 5966 if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return; 5967 } 5968 else 5969 rSt.SeekRel( nLength ); 5970 nReadDg += nLength; 5971 } 5972 while( nReadDg < nLenDg ); 5973 } 5974 5975 sal_Bool SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt, 5976 sal_uLong nLenShapeGroupCont, 5977 sal_Bool bPatriarch, 5978 const unsigned long nDrawingContainerId ) 5979 { 5980 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 5981 long nStartShapeGroupCont = rSt.Tell(); 5982 // Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite) 5983 // und muessen nun 5984 // alle enthaltenen Shape Container abklappern 5985 sal_Bool bFirst = !bPatriarch; 5986 sal_uLong nReadSpGrCont = 0; 5987 do 5988 { 5989 if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) ) 5990 return sal_False; 5991 nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE; 5992 // Shape Container ? 5993 if( DFF_msofbtSpContainer == nFbt ) 5994 { 5995 sal_uLong nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX; 5996 if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) ) 5997 return sal_False; 5998 bFirst = sal_False; 5999 } 6000 else 6001 // eingeschachtelter Shape Group Container ? 6002 if( DFF_msofbtSpgrContainer == nFbt ) 6003 { 6004 if ( !this->GetShapeGroupContainerData( rSt, nLength, sal_False, nDrawingContainerId ) ) 6005 return sal_False; 6006 } 6007 else 6008 rSt.SeekRel( nLength ); 6009 nReadSpGrCont += nLength; 6010 } 6011 while( nReadSpGrCont < nLenShapeGroupCont ); 6012 // den Stream wieder korrekt positionieren 6013 rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont ); 6014 return sal_True; 6015 } 6016 6017 sal_Bool SvxMSDffManager::GetShapeContainerData( SvStream& rSt, 6018 sal_uLong nLenShapeCont, 6019 sal_uLong nPosGroup, 6020 const unsigned long nDrawingContainerId ) 6021 { 6022 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 6023 long nStartShapeCont = rSt.Tell(); 6024 // Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group) 6025 // und muessen nun 6026 // die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe) 6027 // und den ersten BStore Verweis (falls vorhanden) entnehmen 6028 sal_uLong nLenShapePropTbl = 0; 6029 sal_uLong nReadSpCont = 0; 6030 6031 // File Offset des Shape-Containers bzw. der Gruppe(!) vermerken 6032 // 6033 sal_uLong nStartOffs = (ULONG_MAX > nPosGroup) ? 6034 nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE; 6035 SvxMSDffShapeInfo aInfo( nStartOffs ); 6036 6037 // duerfte das Shape durch einen Rahmen ersetzt werden ? 6038 // (vorausgesetzt, es zeigt sich, dass es eine TextBox ist, 6039 // und der Text nicht gedreht ist) 6040 sal_Bool bCanBeReplaced = (ULONG_MAX > nPosGroup) ? sal_False : sal_True; 6041 6042 // wir wissen noch nicht, ob es eine TextBox ist 6043 MSO_SPT eShapeType = mso_sptNil; 6044 MSO_WrapMode eWrapMode = mso_wrapSquare; 6045 // sal_Bool bIsTextBox = sal_False; 6046 6047 // Shape analysieren 6048 // 6049 do 6050 { 6051 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return sal_False; 6052 nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE; 6053 // FSP ? 6054 if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) ) 6055 { 6056 // Wir haben den FSP gefunden: Shape Typ und Id vermerken! 6057 eShapeType = (MSO_SPT)nInst; 6058 rSt >> aInfo.nShapeId; 6059 rSt.SeekRel( nLength - 4 ); 6060 nReadSpCont += nLength; 6061 } 6062 else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ? 6063 { 6064 // Wir haben die Property Table gefunden: 6065 // nach der Blip Property suchen! 6066 sal_uLong nPropRead = 0; 6067 sal_uInt16 nPropId; 6068 sal_uInt32 nPropVal; 6069 nLenShapePropTbl = nLength; 6070 // sal_uInt32 nPropCount = nInst; 6071 long nStartShapePropTbl = rSt.Tell(); 6072 // sal_uInt32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6); 6073 do 6074 { 6075 rSt >> nPropId 6076 >> nPropVal; 6077 nPropRead += 6; 6078 6079 switch( nPropId ) 6080 { 6081 case DFF_Prop_txflTextFlow : 6082 //Writer can now handle vertical textflows in its 6083 //native frames, to only need to do this for the 6084 //other two formats 6085 6086 //Writer will handle all textflow except BtoT 6087 if (GetSvxMSDffSettings() & 6088 (SVXMSDFF_SETTINGS_IMPORT_PPT | 6089 SVXMSDFF_SETTINGS_IMPORT_EXCEL)) 6090 { 6091 if( 0 != nPropVal ) 6092 bCanBeReplaced = false; 6093 } 6094 else if ( 6095 (nPropVal != mso_txflHorzN) && 6096 (nPropVal != mso_txflTtoBA) 6097 ) 6098 { 6099 bCanBeReplaced = false; 6100 } 6101 break; 6102 case DFF_Prop_cdirFont : 6103 //Writer can now handle right to left and left 6104 //to right in its native frames, so only do 6105 //this for the other two formats. 6106 if (GetSvxMSDffSettings() & 6107 (SVXMSDFF_SETTINGS_IMPORT_PPT | 6108 SVXMSDFF_SETTINGS_IMPORT_EXCEL)) 6109 { 6110 if( 0 != nPropVal ) 6111 bCanBeReplaced = sal_False; 6112 } 6113 break; 6114 case DFF_Prop_Rotation : 6115 if( 0 != nPropVal ) 6116 bCanBeReplaced = sal_False; 6117 break; 6118 6119 case DFF_Prop_gtextFStrikethrough : 6120 if( ( 0x20002000 & nPropVal ) == 0x20002000 ) 6121 bCanBeReplaced = sal_False; 6122 break; 6123 6124 case DFF_Prop_fc3DLightFace : 6125 if( ( 0x00080008 & nPropVal ) == 0x00080008 ) 6126 bCanBeReplaced = sal_False; 6127 break; 6128 6129 case DFF_Prop_WrapText : 6130 eWrapMode = (MSO_WrapMode)nPropVal; 6131 break; 6132 6133 default: 6134 { 6135 // Bit gesetzt und gueltig? 6136 if( 0x4000 == ( nPropId & 0xC000 ) ) 6137 { 6138 // Blip Property gefunden: BStore Idx vermerken! 6139 nPropRead = nLenShapePropTbl; 6140 } 6141 else if( 0x8000 & nPropId ) 6142 { 6143 // komplexe Prop gefunden: 6144 // Laenge ist immer 6, nur die Laenge der nach der 6145 // eigentlichen Prop-Table anhaengenden Extra-Daten 6146 // ist unterschiedlich 6147 nPropVal = 6; 6148 } 6149 } 6150 break; 6151 } 6152 6153 /* 6154 //JP 21.04.99: Bug 64510 6155 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge 6156 // Performance einbussen hat. 6157 6158 if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig? 6159 { 6160 // Blip Property gefunden: BStore Idx vermerken! 6161 aInfo.nBStoreIdx = nPropVal; // Index im BStore Container 6162 break; 6163 } 6164 else 6165 if( ( ( (DFF_Prop_txflTextFlow == nPropId) 6166 || (DFF_Prop_Rotation == nPropId) 6167 || (DFF_Prop_cdirFont == nPropId) ) 6168 && (0 != nPropVal) ) 6169 6170 || ( (DFF_Prop_gtextFStrikethrough == nPropId) 6171 && ( (0x20002000 & nPropVal) == 0x20002000) ) // also DFF_Prop_gtextFVertical 6172 || ( (DFF_Prop_fc3DLightFace == nPropId) 6173 && ( (0x00080008 & nPropVal) == 0x00080008) ) // also DFF_Prop_f3D 6174 ) 6175 { 6176 bCanBeReplaced = sal_False; // Mist: gedrehter Text oder 3D-Objekt! 6177 } 6178 else 6179 if( DFF_Prop_WrapText == nPropId ) 6180 { 6181 eWrapMode = (MSO_WrapMode)nPropVal; 6182 } 6183 //////////////////////////////////////////////////////////////// 6184 //////////////////////////////////////////////////////////////// 6185 // keine weitere Property-Auswertung: folge beim Shape-Import // 6186 //////////////////////////////////////////////////////////////// 6187 //////////////////////////////////////////////////////////////// 6188 else 6189 if( 0x8000 & nPropId ) 6190 { 6191 // komplexe Prop gefunden: Laenge lesen und ueberspringen 6192 if(!SkipBytes( rSt, nPropVal )) return sal_False; 6193 nPropRead += nPropVal; 6194 } 6195 */ 6196 } 6197 while( nPropRead < nLenShapePropTbl ); 6198 rSt.Seek( nStartShapePropTbl + nLenShapePropTbl ); 6199 nReadSpCont += nLenShapePropTbl; 6200 } 6201 else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) ) // Text-Box-Story-Eintrag gefunden 6202 { 6203 rSt >> aInfo.nTxBxComp; 6204 // --> OD 2008-07-28 #156763# 6205 // Add internal drawing container id to text id. 6206 // Note: The text id uses the first two bytes, while the internal 6207 // drawing container id used the second two bytes. 6208 aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) + 6209 nDrawingContainerId; 6210 DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId, 6211 "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." ); 6212 // <-- 6213 } 6214 else 6215 { 6216 rSt.SeekRel( nLength ); 6217 nReadSpCont += nLength; 6218 } 6219 } 6220 while( nReadSpCont < nLenShapeCont ); 6221 6222 // 6223 // Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern 6224 // 6225 if( aInfo.nShapeId ) 6226 { 6227 // fuer Textboxen ggfs. ersetzen durch Rahmen erlauben 6228 if( bCanBeReplaced 6229 && aInfo.nTxBxComp 6230 && ( 6231 ( eShapeType == mso_sptTextSimple ) 6232 || ( eShapeType == mso_sptTextBox ) 6233 || ( ( ( eShapeType == mso_sptRectangle ) 6234 || ( eShapeType == mso_sptRoundRectangle ) 6235 ) 6236 ) ) ) 6237 { 6238 aInfo.bReplaceByFly = sal_True; 6239 } 6240 pShapeInfos->Insert( new SvxMSDffShapeInfo( aInfo ) ); 6241 pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ), 6242 pShapeOrders->Count() ); 6243 } 6244 6245 // und den Stream wieder korrekt positionieren 6246 rSt.Seek( nStartShapeCont + nLenShapeCont ); 6247 return sal_True; 6248 } 6249 6250 6251 6252 /***************************************************************************** 6253 6254 Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id) 6255 ---------------------------------- 6256 ******************************************************************************/ 6257 sal_Bool SvxMSDffManager::GetShape(sal_uLong nId, SdrObject*& rpShape, 6258 SvxMSDffImportData& rData) 6259 { 6260 SvxMSDffShapeInfo aTmpRec(0, nId); 6261 aTmpRec.bSortByShapeId = sal_True; 6262 6263 sal_uInt16 nFound; 6264 if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) ) 6265 { 6266 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound ); 6267 6268 // eventuell altes Errorflag loeschen 6269 if( rStCtrl.GetError() ) 6270 rStCtrl.ResetError(); 6271 // FilePos des/der Stream(s) merken 6272 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 6273 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 6274 // das Shape im Steuer Stream anspringen 6275 rStCtrl.Seek( rInfo.nFilePos ); 6276 6277 // Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt! 6278 if( rStCtrl.GetError() ) 6279 rStCtrl.ResetError(); 6280 else 6281 rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect ); 6282 6283 // alte FilePos des/der Stream(s) restaurieren 6284 rStCtrl.Seek( nOldPosCtrl ); 6285 if( &rStCtrl != pStData ) 6286 pStData->Seek( nOldPosData ); 6287 return ( 0 != rpShape ); 6288 } 6289 return sal_False; 6290 } 6291 6292 6293 6294 /* Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr) 6295 --------------------------------- 6296 ******************************************************************************/ 6297 sal_Bool SvxMSDffManager::GetBLIP( sal_uLong nIdx_, Graphic& rData, Rectangle* pVisArea ) const 6298 { 6299 sal_Bool bOk = sal_False; // Ergebnisvariable initialisieren 6300 if ( pStData ) 6301 { 6302 // check if a graphic for this blipId is already imported 6303 if ( nIdx_ && pEscherBlipCache ) 6304 { 6305 EscherBlipCacheEntry* pEntry; 6306 for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry; 6307 pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() ) 6308 { 6309 if ( pEntry->nBlip == nIdx_ ) 6310 { /* if this entry is available, then it should be possible 6311 to get the Graphic via GraphicObject */ 6312 GraphicObject aGraphicObject( pEntry->aUniqueID ); 6313 rData = aGraphicObject.GetGraphic(); 6314 if ( rData.GetType() != GRAPHIC_NONE ) 6315 bOk = sal_True; 6316 else 6317 delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove(); 6318 break; 6319 } 6320 } 6321 } 6322 if ( !bOk ) 6323 { 6324 sal_uInt16 nIdx = sal_uInt16( nIdx_ ); 6325 if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return sal_False; 6326 6327 // eventuell alte(s) Errorflag(s) loeschen 6328 if( rStCtrl.GetError() ) 6329 rStCtrl.ResetError(); 6330 if( ( &rStCtrl != pStData ) 6331 && pStData->GetError() ) 6332 pStData->ResetError(); 6333 6334 // FilePos des/der Stream(s) merken 6335 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 6336 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 6337 6338 // passende Info-Struct aus unserem Pointer Array nehmen 6339 SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ]; 6340 6341 // das BLIP Atom im Daten Stream anspringen 6342 pStData->Seek( rInfo.nFilePos ); 6343 // ggfs. Fehlerstatus zuruecksetzen 6344 if( pStData->GetError() ) 6345 pStData->ResetError(); 6346 else 6347 bOk = GetBLIPDirect( *pStData, rData, pVisArea ); 6348 if( pStData2 && !bOk ) 6349 { 6350 // Fehler, aber zweite Chance: es gibt noch einen zweiten 6351 // Datenstream, in dem die Grafik liegen koennte! 6352 if( pStData2->GetError() ) 6353 pStData2->ResetError(); 6354 sal_uLong nOldPosData2 = pStData2->Tell(); 6355 // das BLIP Atom im zweiten Daten Stream anspringen 6356 pStData2->Seek( rInfo.nFilePos ); 6357 // ggfs. Fehlerstatus zuruecksetzen 6358 if( pStData2->GetError() ) 6359 pStData2->ResetError(); 6360 else 6361 bOk = GetBLIPDirect( *pStData2, rData, pVisArea ); 6362 // alte FilePos des zweiten Daten-Stream restaurieren 6363 pStData2->Seek( nOldPosData2 ); 6364 } 6365 // alte FilePos des/der Stream(s) restaurieren 6366 rStCtrl.Seek( nOldPosCtrl ); 6367 if( &rStCtrl != pStData ) 6368 pStData->Seek( nOldPosData ); 6369 6370 if ( bOk ) 6371 { 6372 // create new BlipCacheEntry for this graphic 6373 GraphicObject aGraphicObject( rData ); 6374 if ( !pEscherBlipCache ) 6375 const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List(); 6376 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() ); 6377 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND ); 6378 } 6379 } 6380 } 6381 return bOk; 6382 } 6383 6384 /* Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream) 6385 --------------------------------- 6386 ******************************************************************************/ 6387 sal_Bool SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const 6388 { 6389 sal_uLong nOldPos = rBLIPStream.Tell(); 6390 6391 int nRes = GRFILTER_OPENERROR; // Fehlervariable initialisieren 6392 6393 // nachschauen, ob es sich auch wirklich um ein BLIP handelt 6394 sal_uInt32 nLength; 6395 sal_uInt16 nInst, nFbt( 0 ); 6396 sal_uInt8 nVer; 6397 if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) ) 6398 { 6399 Size aMtfSize100; 6400 sal_Bool bMtfBLIP = sal_False; 6401 sal_Bool bZCodecCompression = sal_False; 6402 // Nun exakt auf den Beginn der eingebetteten Grafik positionieren 6403 sal_uLong nSkip = ( nInst & 0x0001 ) ? 32 : 16; 6404 6405 switch( nInst & 0xFFFE ) 6406 { 6407 case 0x216 : // Metafile header then compressed WMF 6408 case 0x3D4 : // Metafile header then compressed EMF 6409 case 0x542 : // Metafile hd. then compressed PICT 6410 { 6411 rBLIPStream.SeekRel( nSkip + 20 ); 6412 6413 // read in size of metafile in EMUS 6414 rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height(); 6415 6416 // scale to 1/100mm 6417 aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360; 6418 6419 if ( pVisArea ) // seem that we currently are skipping the visarea position 6420 *pVisArea = Rectangle( Point(), aMtfSize100 ); 6421 6422 // skip rest of header 6423 nSkip = 6; 6424 bMtfBLIP = bZCodecCompression = sal_True; 6425 } 6426 break; 6427 case 0x46A : // One byte tag then JPEG (= JFIF) data 6428 case 0x6E0 : // One byte tag then PNG data 6429 case 0x6E2 : // One byte tag then JPEG in CMYK color space 6430 case 0x7A8 : 6431 nSkip += 1; // One byte tag then DIB data 6432 break; 6433 } 6434 rBLIPStream.SeekRel( nSkip ); 6435 6436 SvStream* pGrStream = &rBLIPStream; 6437 SvMemoryStream* pOut = NULL; 6438 if( bZCodecCompression ) 6439 { 6440 pOut = new SvMemoryStream( 0x8000, 0x4000 ); 6441 ZCodec aZCodec( 0x8000, 0x8000 ); 6442 aZCodec.BeginCompression(); 6443 aZCodec.Decompress( rBLIPStream, *pOut ); 6444 aZCodec.EndCompression(); 6445 pOut->Seek( STREAM_SEEK_TO_BEGIN ); 6446 pOut->SetResizeOffset( 0 ); // sj: #i102257# setting ResizeOffset of 0 prevents from seeking 6447 // behind the stream end (allocating too much memory) 6448 pGrStream = pOut; 6449 } 6450 6451 //#define DBG_EXTRACTGRAPHICS 6452 #ifdef DBG_EXTRACTGRAPHICS 6453 6454 static sal_Int32 nCount; 6455 6456 String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) ); 6457 aFileName.Append( String::CreateFromInt32( nCount++ ) ); 6458 switch( nInst &~ 1 ) 6459 { 6460 case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break; 6461 case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break; 6462 case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break; 6463 case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break; 6464 case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break; 6465 case 0x6e2 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break; 6466 case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break; 6467 } 6468 6469 String aURLStr; 6470 6471 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) ) 6472 { 6473 INetURLObject aURL( aURLStr ); 6474 6475 aURL.removeSegment(); 6476 aURL.removeFinalSlash(); 6477 aURL.Append( aFileName ); 6478 6479 SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE ); 6480 6481 if( pDbgOut ) 6482 { 6483 if ( bZCodecCompression ) 6484 { 6485 pOut->Seek( STREAM_SEEK_TO_END ); 6486 pDbgOut->Write( pOut->GetData(), pOut->Tell() ); 6487 pOut->Seek( STREAM_SEEK_TO_BEGIN ); 6488 } 6489 else 6490 { 6491 sal_Int32 nDbgLen = nLength - nSkip; 6492 if ( nDbgLen ) 6493 { 6494 sal_Char* pDat = new sal_Char[ nDbgLen ]; 6495 pGrStream->Read( pDat, nDbgLen ); 6496 pDbgOut->Write( pDat, nDbgLen ); 6497 pGrStream->SeekRel( -nDbgLen ); 6498 delete[] pDat; 6499 } 6500 } 6501 6502 delete pDbgOut; 6503 } 6504 } 6505 #endif 6506 6507 if( ( nInst & 0xFFFE ) == 0x7A8 ) 6508 { // DIBs direkt holen 6509 Bitmap aNew; 6510 if( aNew.Read( *pGrStream, sal_False ) ) 6511 { 6512 rData = Graphic( aNew ); 6513 nRes = GRFILTER_OK; 6514 } 6515 } 6516 else 6517 { // und unsere feinen Filter darauf loslassen 6518 GraphicFilter* pGF = GraphicFilter::GetGraphicFilter(); 6519 String aEmptyStr; 6520 nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW ); 6521 6522 // SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems, 6523 // then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the 6524 // scaling has been implemented does not happen anymore. 6525 // 6526 // For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the 6527 // dxarray is empty (this has been solved in wmf/emf but not for pict) 6528 if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) ) 6529 { 6530 if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) ) 6531 { // #75956#, scaling does not work properly, if the graphic is less than 1cm 6532 GDIMetaFile aMtf( rData.GetGDIMetaFile() ); 6533 const Size aOldSize( aMtf.GetPrefSize() ); 6534 6535 if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) && 6536 aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) ) 6537 { 6538 aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(), 6539 (double) aMtfSize100.Height() / aOldSize.Height() ); 6540 aMtf.SetPrefSize( aMtfSize100 ); 6541 aMtf.SetPrefMapMode( MAP_100TH_MM ); 6542 rData = aMtf; 6543 } 6544 } 6545 } 6546 } 6547 // ggfs. Fehlerstatus zuruecksetzen 6548 if ( ERRCODE_IO_PENDING == pGrStream->GetError() ) 6549 pGrStream->ResetError(); 6550 delete pOut; 6551 } 6552 rBLIPStream.Seek( nOldPos ); // alte FilePos des Streams restaurieren 6553 6554 return ( GRFILTER_OK == nRes ); // Ergebniss melden 6555 } 6556 6557 /* static */ 6558 sal_Bool SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn) 6559 { 6560 rRec.nFilePos = rIn.Tell(); 6561 return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer, 6562 rRec.nRecInstance, 6563 rRec.nRecType, 6564 rRec.nRecLen ); 6565 } 6566 6567 6568 /* auch static */ 6569 sal_Bool SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt, 6570 sal_uInt8& rVer, 6571 sal_uInt16& rInst, 6572 sal_uInt16& rFbt, 6573 sal_uInt32& rLength ) 6574 { 6575 sal_uInt16 nTmp; 6576 rSt >> nTmp >> rFbt >> rLength; 6577 rVer = sal::static_int_cast< sal_uInt8 >(nTmp & 15); 6578 rInst = nTmp >> 4; 6579 if ( rLength > ( SAL_MAX_UINT32 - rSt.Tell() ) ) // preserving overflow, optimal would be to check 6580 rSt.SetError( SVSTREAM_FILEFORMAT_ERROR ); // the record size against the parent header 6581 return rSt.GetError() == 0; 6582 } 6583 6584 6585 6586 6587 sal_Bool SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, sal_uLong nDatLen, 6588 char*& rpBuff, sal_uInt32& rBuffLen ) const 6589 { 6590 if( nDatLen ) 6591 { 6592 rpBuff = new (std::nothrow) char[ nDatLen ]; 6593 rBuffLen = nDatLen; 6594 rStData.Read( rpBuff, nDatLen ); 6595 } 6596 return sal_True; 6597 } 6598 6599 sal_Bool SvxMSDffManager::ProcessClientData(SvStream& rStData, sal_uLong nDatLen, 6600 char*& rpBuff, sal_uInt32& rBuffLen ) const 6601 { 6602 if( nDatLen ) 6603 { 6604 rpBuff = new (std::nothrow) char[ nDatLen ]; 6605 if ( rpBuff ) 6606 { 6607 rBuffLen = nDatLen; 6608 rStData.Read( rpBuff, nDatLen ); 6609 } 6610 } 6611 return sal_True; 6612 } 6613 6614 6615 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ ) 6616 { 6617 return; // wird von SJ im Draw ueberladen 6618 } 6619 6620 sal_uLong SvxMSDffManager::Calc_nBLIPPos( sal_uLong nOrgVal, sal_uLong /* nStreamPos */ ) const 6621 { 6622 return nOrgVal; 6623 } 6624 6625 sal_Bool SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const 6626 { 6627 return sal_False; 6628 } 6629 6630 sal_Bool SvxMSDffManager::ShapeHasText( sal_uLong /* nShapeId */, sal_uLong /* nFilePos */ ) const 6631 { 6632 return sal_True; 6633 } 6634 6635 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup> 6636 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId, 6637 const Graphic& rGrf, 6638 const Rectangle& rBoundRect, 6639 const Rectangle& rVisArea, 6640 const int /* _nCalledByGroup */, 6641 sal_Int64 nAspect ) const 6642 // <-- 6643 { 6644 SdrObject* pRet = 0; 6645 String sStorageName; 6646 SvStorageRef xSrcStg; 6647 ErrCode nError = ERRCODE_NONE; 6648 uno::Reference < embed::XStorage > xDstStg; 6649 if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg )) 6650 pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg, 6651 rGrf, rBoundRect, rVisArea, pStData, nError, 6652 nSvxMSDffOLEConvFlags, nAspect ); 6653 return pRet; 6654 } 6655 6656 sal_Bool SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf ) 6657 { 6658 String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) ); 6659 SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream ); 6660 xStm->SetVersion( pStor->GetVersion() ); 6661 xStm->SetBufferSize( 8192 ); 6662 6663 sal_uInt16 nAspect = ASPECT_CONTENT; 6664 sal_uLong nAdviseModes = 2; 6665 6666 Impl_OlePres aEle( FORMAT_GDIMETAFILE ); 6667 // Die Groesse in 1/100 mm umrechnen 6668 // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird, 6669 // versucht SV einen BestMatchden richtigen Wert zu raten. 6670 Size aSize = rMtf.GetPrefSize(); 6671 MapMode aMMSrc = rMtf.GetPrefMapMode(); 6672 MapMode aMMDst( MAP_100TH_MM ); 6673 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst ); 6674 aEle.SetSize( aSize ); 6675 aEle.SetAspect( nAspect ); 6676 aEle.SetAdviseFlags( nAdviseModes ); 6677 aEle.SetMtf( rMtf ); 6678 aEle.Write( *xStm ); 6679 6680 xStm->SetBufferSize( 0 ); 6681 return xStm->GetError() == SVSTREAM_OK; 6682 } 6683 6684 struct ClsIDs { 6685 sal_uInt32 nId; 6686 const sal_Char* pSvrName; 6687 const sal_Char* pDspName; 6688 }; 6689 static ClsIDs aClsIDs[] = { 6690 6691 { 0x000212F0, "MSWordArt", "Microsoft Word Art" }, 6692 { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" }, 6693 6694 // MS Apps 6695 { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" }, 6696 { 0x00030001, "ExcelChart", "Microsoft Excel Chart" }, 6697 { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" }, 6698 { 0x00030003, "WordDocument", "Microsoft Word Document" }, 6699 { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" }, 6700 { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"}, 6701 { 0x00030006, "MSGraph", "Microsoft Graph" }, 6702 { 0x00030007, "MSDraw", "Microsoft Draw" }, 6703 { 0x00030008, "Note-It", "Microsoft Note-It" }, 6704 { 0x00030009, "WordArt", "Microsoft Word Art" }, 6705 { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" }, 6706 { 0x0003000b, "Equation", "Microsoft Equation Editor" }, 6707 { 0x0003000c, "Package", "Package" }, 6708 { 0x0003000d, "SoundRec", "Sound" }, 6709 { 0x0003000e, "MPlayer", "Media Player" }, 6710 // MS Demos 6711 { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" }, 6712 { 0x00030010, "Srtest", "OLE 1.0 Test Demo" }, 6713 { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" }, 6714 { 0x00030012, "OleDemo", "OLE 1.0 Demo" }, 6715 6716 // Coromandel / Dorai Swamy / 718-793-7963 6717 { 0x00030013, "CoromandelIntegra", "Coromandel Integra" }, 6718 { 0x00030014, "CoromandelObjServer","Coromandel Object Server" }, 6719 6720 // 3-d Visions Corp / Peter Hirsch / 310-325-1339 6721 { 0x00030015, "StanfordGraphics", "Stanford Graphics" }, 6722 6723 // Deltapoint / Nigel Hearne / 408-648-4000 6724 { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" }, 6725 { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" }, 6726 6727 // Corel / Richard V. Woodend / 613-728-8200 x1153 6728 { 0x00030018, "PhotoPaint", "Corel PhotoPaint" }, 6729 { 0x00030019, "CShow", "Corel Show" }, 6730 { 0x0003001a, "CorelChart", "Corel Chart" }, 6731 { 0x0003001b, "CDraw", "Corel Draw" }, 6732 6733 // Inset Systems / Mark Skiba / 203-740-2400 6734 { 0x0003001c, "HJWIN1.0", "Inset Systems" }, 6735 6736 // Mark V Systems / Mark McGraw / 818-995-7671 6737 { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" }, 6738 6739 // IdentiTech / Mike Gilger / 407-951-9503 6740 { 0x0003001e, "FYI", "IdentiTech FYI" }, 6741 { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" }, 6742 6743 // Inventa Corporation / Balaji Varadarajan / 408-987-0220 6744 { 0x00030020, "Stickynote", "Inventa Sticky Note" }, 6745 6746 // ShapeWare Corp. / Lori Pearce / 206-467-6723 6747 { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" }, 6748 { 0x00030022, "ImportServer", "Spaheware Import Server" }, 6749 6750 // test app SrTest 6751 { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" }, 6752 6753 // test app ClTest. Doesn't really work as a server but is in reg db 6754 { 0x00030025, "Cltest", "OLE 1.0 Client Test" }, 6755 6756 // Microsoft ClipArt Gallery Sherry Larsen-Holmes 6757 { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" }, 6758 // Microsoft Project Cory Reina 6759 { 0x00030027, "MSProject", "Microsoft Project" }, 6760 6761 // Microsoft Works Chart 6762 { 0x00030028, "MSWorksChart", "Microsoft Works Chart" }, 6763 6764 // Microsoft Works Spreadsheet 6765 { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" }, 6766 6767 // AFX apps - Dean McCrory 6768 { 0x0003002A, "MinSvr", "AFX Mini Server" }, 6769 { 0x0003002B, "HierarchyList", "AFX Hierarchy List" }, 6770 { 0x0003002C, "BibRef", "AFX BibRef" }, 6771 { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" }, 6772 { 0x0003002E, "TestServ", "AFX Test Server" }, 6773 6774 // Ami Pro 6775 { 0x0003002F, "AmiProDocument", "Ami Pro Document" }, 6776 6777 // WordPerfect Presentations For Windows 6778 { 0x00030030, "WPGraphics", "WordPerfect Presentation" }, 6779 { 0x00030031, "WPCharts", "WordPerfect Chart" }, 6780 6781 // MicroGrafx Charisma 6782 { 0x00030032, "Charisma", "MicroGrafx Charisma" }, 6783 { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" }, 6784 { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" }, 6785 // MicroGrafx Draw 6786 { 0x00030035, "Draw", "MicroGrafx Draw" }, 6787 // MicroGrafx Designer 6788 { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" }, 6789 6790 // STAR DIVISION 6791 // { 0x000424CA, "StarMath", "StarMath 1.0" }, 6792 { 0x00043AD2, "FontWork", "Star FontWork" }, 6793 // { 0x000456EE, "StarMath2", "StarMath 2.0" }, 6794 6795 { 0, "", "" } }; 6796 6797 6798 sal_Bool SvxMSDffManager::ConvertToOle2( SvStream& rStm, sal_uInt32 nReadLen, 6799 const GDIMetaFile * pMtf, const SotStorageRef& rDest ) 6800 { 6801 sal_Bool bMtfRead = sal_False; 6802 SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ), 6803 STREAM_WRITE| STREAM_SHARE_DENYALL ); 6804 if( xOle10Stm->GetError() ) 6805 return sal_False; 6806 6807 sal_uInt32 nType; 6808 sal_uInt32 nRecType; 6809 sal_uInt32 nStrLen; 6810 String aSvrName; 6811 sal_uInt32 nDummy0; 6812 sal_uInt32 nDummy1; 6813 sal_uInt32 nDataLen; 6814 sal_uInt8 * pData; 6815 sal_uInt32 nBytesRead = 0; 6816 do 6817 { 6818 rStm >> nType; 6819 rStm >> nRecType; 6820 rStm >> nStrLen; 6821 if( nStrLen ) 6822 { 6823 if( 0x10000L > nStrLen ) 6824 { 6825 sal_Char * pBuf = new sal_Char[ nStrLen ]; 6826 rStm.Read( pBuf, nStrLen ); 6827 aSvrName.Assign( String( pBuf, (sal_uInt16) nStrLen-1, gsl_getSystemTextEncoding() ) ); 6828 delete[] pBuf; 6829 } 6830 else 6831 break; 6832 } 6833 rStm >> nDummy0; 6834 rStm >> nDummy1; 6835 rStm >> nDataLen; 6836 6837 nBytesRead += 6 * sizeof( sal_uInt32 ) + nStrLen + nDataLen; 6838 6839 if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen ) 6840 { 6841 if( xOle10Stm.Is() ) 6842 { 6843 pData = new sal_uInt8[ nDataLen ]; 6844 if( !pData ) 6845 return sal_False; 6846 6847 rStm.Read( pData, nDataLen ); 6848 6849 // write to ole10 stream 6850 *xOle10Stm << nDataLen; 6851 xOle10Stm->Write( pData, nDataLen ); 6852 xOle10Stm = SotStorageStreamRef(); 6853 6854 // set the compobj stream 6855 ClsIDs* pIds; 6856 for( pIds = aClsIDs; pIds->nId; pIds++ ) 6857 { 6858 if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) ) 6859 break; 6860 } 6861 // SvGlobalName* pClsId = NULL; 6862 String aShort, aFull; 6863 if( pIds->nId ) 6864 { 6865 // gefunden! 6866 sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName ); 6867 rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt, 6868 String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) ); 6869 } 6870 else 6871 { 6872 sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName ); 6873 rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName ); 6874 } 6875 6876 delete[] pData; 6877 } 6878 else if( nRecType == 5 && !pMtf ) 6879 { 6880 sal_uLong nPos = rStm.Tell(); 6881 sal_uInt16 sz[4]; 6882 rStm.Read( sz, 8 ); 6883 //rStm.SeekRel( 8 ); 6884 Graphic aGraphic; 6885 if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() ) 6886 { 6887 const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile(); 6888 MakeContentStream( rDest, rMtf ); 6889 bMtfRead = sal_True; 6890 } 6891 // set behind the data 6892 rStm.Seek( nPos + nDataLen ); 6893 } 6894 else 6895 rStm.SeekRel( nDataLen ); 6896 } 6897 } while( !rStm.IsEof() && nReadLen >= nBytesRead ); 6898 6899 if( !bMtfRead && pMtf ) 6900 { 6901 MakeContentStream( rDest, *pMtf ); 6902 return sal_True; 6903 } 6904 6905 return sal_False; 6906 } 6907 6908 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName ) 6909 { 6910 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) 6911 || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) ) 6912 return "swriter"; 6913 else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) 6914 || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) ) 6915 return "scalc"; 6916 else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) 6917 || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) 6918 return "simpress"; 6919 else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) 6920 || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) 6921 return "sdraw"; 6922 else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) 6923 || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) ) 6924 return "smath"; 6925 else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) 6926 || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) 6927 return "schart"; 6928 return 0; 6929 } 6930 6931 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName ) 6932 { 6933 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) ) 6934 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) ); 6935 6936 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) ) 6937 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) ); 6938 6939 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) ) 6940 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) ); 6941 6942 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) ) 6943 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) ); 6944 6945 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) ) 6946 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) ); 6947 6948 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) 6949 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) ); 6950 6951 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) ) 6952 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) ); 6953 6954 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) 6955 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) ); 6956 6957 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) ) 6958 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) ); 6959 6960 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) ) 6961 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) ); 6962 6963 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) ) 6964 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) ); 6965 6966 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) 6967 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) ); 6968 6969 return ::rtl::OUString(); 6970 } 6971 6972 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > SvxMSDffManager::CheckForConvertToSOObj( sal_uInt32 nConvertFlags, 6973 SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage, 6974 const Graphic& rGrf, 6975 const Rectangle& rVisArea ) 6976 { 6977 uno::Reference < embed::XEmbeddedObject > xObj; 6978 SvGlobalName aStgNm = rSrcStg.GetClassName(); 6979 const char* pName = GetInternalServerName_Impl( aStgNm ); 6980 String sStarName; 6981 if ( pName ) 6982 sStarName = String::CreateFromAscii( pName ); 6983 else if ( nConvertFlags ) 6984 { 6985 static struct _ObjImpType 6986 { 6987 sal_uInt32 nFlag; 6988 const char* pFactoryNm; 6989 // GlobalNameId 6990 sal_uInt32 n1; 6991 sal_uInt16 n2, n3; 6992 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15; 6993 } aArr[] = { 6994 { OLE_MATHTYPE_2_STARMATH, "smath", 6995 0x0002ce02L, 0x0000, 0x0000, 6996 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 6997 { OLE_MATHTYPE_2_STARMATH, "smath", 6998 0x00021700L, 0x0000, 0x0000, 6999 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7000 { OLE_WINWORD_2_STARWRITER, "swriter", 7001 0x00020906L, 0x0000, 0x0000, 7002 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7003 { OLE_EXCEL_2_STARCALC, "scalc", // Excel table 7004 0x00020810L, 0x0000, 0x0000, 7005 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7006 { OLE_EXCEL_2_STARCALC, "scalc", // Excel chart 7007 0x00020820L, 0x0000, 0x0000, 7008 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7009 // 114465: additional Excel OLE chart classId to above. 7010 { OLE_EXCEL_2_STARCALC, "scalc", 7011 0x00020821L, 0x0000, 0x0000, 7012 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7013 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint presentation 7014 0x64818d10L, 0x4f9b, 0x11cf, 7015 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 }, 7016 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint slide 7017 0x64818d11L, 0x4f9b, 0x11cf, 7018 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 }, 7019 { 0, 0, 7020 0, 0, 0, 7021 0, 0, 0, 0, 0, 0, 0, 0 } 7022 }; 7023 7024 for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr ) 7025 { 7026 if( nConvertFlags & pArr->nFlag ) 7027 { 7028 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3, 7029 pArr->b8, pArr->b9, pArr->b10, pArr->b11, 7030 pArr->b12, pArr->b13, pArr->b14, pArr->b15 ); 7031 7032 if ( aStgNm == aTypeName ) 7033 { 7034 sStarName = String::CreateFromAscii( pArr->pFactoryNm ); 7035 break; 7036 } 7037 } 7038 } 7039 } 7040 7041 if ( sStarName.Len() ) 7042 { 7043 //TODO/MBA: check if (and when) storage and stream will be destroyed! 7044 const SfxFilter* pFilter = 0; 7045 SvMemoryStream* pStream = new SvMemoryStream; 7046 if ( pName ) 7047 { 7048 // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also 7049 SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ ); 7050 *xStr >> *pStream; 7051 } 7052 else 7053 { 7054 SfxFilterMatcher aMatch( sStarName ); 7055 SotStorageRef xStorage = new SotStorage( sal_False, *pStream ); 7056 rSrcStg.CopyTo( xStorage ); 7057 xStorage->Commit(); 7058 xStorage.Clear(); 7059 String aType = SfxFilter::GetTypeFromStorage( rSrcStg ); 7060 if ( aType.Len() ) 7061 pFilter = aMatch.GetFilter4EA( aType ); 7062 } 7063 7064 if ( pName || pFilter ) 7065 { 7066 //Reuse current ole name 7067 String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj))); 7068 aDstStgName += String::CreateFromInt32(nMSOleObjCntr); 7069 7070 ::rtl::OUString aFilterName; 7071 if ( pFilter ) 7072 aFilterName = pFilter->GetName(); 7073 else 7074 aFilterName = GetFilterNameFromClassID_Impl( aStgNm ); 7075 7076 uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2); 7077 aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) ); 7078 uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream ); 7079 aMedium[0].Value <<= xStream; 7080 aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 7081 aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ); 7082 7083 if ( aFilterName.getLength() ) 7084 { 7085 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); 7086 aMedium[2].Value <<= aFilterName; 7087 } 7088 7089 ::rtl::OUString aName( aDstStgName ); 7090 comphelper::EmbeddedObjectContainer aCnt( rDestStorage ); 7091 xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); 7092 7093 if ( !xObj.is() ) 7094 { 7095 if( aFilterName.getLength() ) 7096 { 7097 // throw the filter parameter away as workaround 7098 aMedium.realloc( 2 ); 7099 xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); 7100 } 7101 7102 if ( !xObj.is() ) 7103 return xObj; 7104 } 7105 7106 // TODO/LATER: ViewAspect must be passed from outside! 7107 sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT; 7108 7109 // JP 26.10.2001: Bug 93374 / 91928 the writer 7110 // objects need the correct visarea needs the 7111 // correct visarea, but this is not true for 7112 // PowerPoint (see bugdoc 94908b) 7113 // SJ: 19.11.2001 bug 94908, also chart objects 7114 // needs the correct visarea 7115 7116 // If pName is set this is an own embedded object, it should have the correct size internally 7117 // TODO/LATER: it might make sence in future to set the size stored in internal object 7118 if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) ) 7119 { 7120 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) ); 7121 Size aSz; 7122 if ( rVisArea.IsEmpty() ) 7123 aSz = lcl_GetPrefSize(rGrf, aMapMode ); 7124 else 7125 { 7126 aSz = rVisArea.GetSize(); 7127 aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode ); 7128 } 7129 7130 // don't modify the object 7131 //TODO/LATER: remove those hacks, that needs to be done differently! 7132 //xIPObj->EnableSetModified( sal_False ); 7133 awt::Size aSize; 7134 aSize.Width = aSz.Width(); 7135 aSize.Height = aSz.Height(); 7136 xObj->setVisualAreaSize( nViewAspect, aSize ); 7137 //xIPObj->EnableSetModified( sal_True ); 7138 } 7139 else if ( sStarName.EqualsAscii( "smath" ) ) 7140 { // SJ: force the object to recalc its visarea 7141 //TODO/LATER: wait for PrinterChangeNotification 7142 //xIPObj->OnDocumentPrinterChanged( NULL ); 7143 } 7144 } 7145 } 7146 7147 return xObj; 7148 } 7149 7150 // TODO/MBA: code review and testing! 7151 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage( 7152 const String& rStorageName, 7153 SotStorageRef& rSrcStorage, 7154 const uno::Reference < embed::XStorage >& xDestStorage, 7155 const Graphic& rGrf, 7156 const Rectangle& rBoundRect, 7157 const Rectangle& rVisArea, 7158 SvStream* pDataStrm, 7159 ErrCode& rError, 7160 sal_uInt32 nConvertFlags, 7161 sal_Int64 nReccomendedAspect ) 7162 { 7163 sal_Int64 nAspect = nReccomendedAspect; 7164 SdrOle2Obj* pRet = 0; 7165 if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() ) 7166 { 7167 comphelper::EmbeddedObjectContainer aCnt( xDestStorage ); 7168 // Ist der 01Ole-Stream ueberhaupt vorhanden ? 7169 // ( ist er z.B. bei FontWork nicht ) 7170 // Wenn nicht -> Einbindung als Grafik 7171 sal_Bool bValidStorage = sal_False; 7172 String aDstStgName( String::CreateFromAscii( 7173 RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj))); 7174 7175 aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr ); 7176 7177 { 7178 SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName, 7179 STREAM_READWRITE| STREAM_SHARE_DENYALL ); 7180 if( xObjStg.Is() ) 7181 { 7182 { 7183 sal_uInt8 aTestA[10]; // exist the \1CompObj-Stream ? 7184 SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream( 7185 String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"), 7186 RTL_TEXTENCODING_MS_1252 )); 7187 bValidStorage = xSrcTst.Is() && sizeof( aTestA ) == 7188 xSrcTst->Read( aTestA, sizeof( aTestA ) ); 7189 if( !bValidStorage ) 7190 { 7191 // or the \1Ole-Stream ? 7192 xSrcTst = xObjStg->OpenSotStream( 7193 String(RTL_CONSTASCII_STRINGPARAM("\1Ole"), 7194 RTL_TEXTENCODING_MS_1252 )); 7195 bValidStorage = xSrcTst.Is() && sizeof(aTestA) == 7196 xSrcTst->Read(aTestA, sizeof(aTestA)); 7197 } 7198 } 7199 7200 if( bValidStorage ) 7201 { 7202 if ( nAspect != embed::Aspects::MSOLE_ICON ) 7203 { 7204 // check whether the object is iconified one 7205 // usually this information is already known, the only exception 7206 // is a kind of embedded objects in Word documents 7207 // TODO/LATER: should the caller be notified if the aspect changes in future? 7208 7209 SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream( 7210 String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ), 7211 STREAM_STD_READ | STREAM_NOCREATE ); 7212 if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() ) 7213 { 7214 sal_uInt8 nByte = 0; 7215 *xObjInfoSrc >> nByte; 7216 if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON ) 7217 nAspect = embed::Aspects::MSOLE_ICON; 7218 } 7219 } 7220 7221 uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj( 7222 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea )); 7223 if ( xObj.is() ) 7224 { 7225 svt::EmbeddedObjectRef aObj( xObj, nAspect ); 7226 7227 // TODO/LATER: need MediaType 7228 aObj.SetGraphic( rGrf, ::rtl::OUString() ); 7229 7230 // TODO/MBA: check setting of PersistName 7231 pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false); 7232 // we have the Object, don't create another 7233 bValidStorage = false; 7234 } 7235 } 7236 } 7237 } 7238 7239 if( bValidStorage ) 7240 { 7241 // object is not an own object 7242 SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE ); 7243 7244 if ( xObjStor.Is() ) 7245 { 7246 SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ ); 7247 xSrcStor->CopyTo( xObjStor ); 7248 7249 if( !xObjStor->GetError() ) 7250 xObjStor->Commit(); 7251 7252 if( xObjStor->GetError() ) 7253 { 7254 rError = xObjStor->GetError(); 7255 bValidStorage = sal_False; 7256 } 7257 else if( !xObjStor.Is() ) 7258 bValidStorage = sal_False; 7259 } 7260 } 7261 else if( pDataStrm ) 7262 { 7263 sal_uInt32 nLen, nDummy; 7264 *pDataStrm >> nLen >> nDummy; 7265 if( SVSTREAM_OK != pDataStrm->GetError() || 7266 // Id in BugDoc - exist there other Ids? 7267 // The ConvertToOle2 - does not check for consistent 7268 0x30008 != nDummy ) 7269 bValidStorage = sal_False; 7270 else 7271 { 7272 // or is it an OLE-1 Stream in the DataStream? 7273 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName ); 7274 //TODO/MBA: remove metafile conversion from ConvertToOle2 7275 //when is this code used?! 7276 GDIMetaFile aMtf; 7277 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor ); 7278 xObjStor->Commit(); 7279 } 7280 } 7281 7282 if( bValidStorage ) 7283 { 7284 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName ); 7285 if( xObj.is() ) 7286 { 7287 // the visual area must be retrieved from the metafile (object doesn't know it so far) 7288 7289 if ( nAspect != embed::Aspects::MSOLE_ICON ) 7290 { 7291 // working with visual area can switch the object to running state 7292 awt::Size aAwtSz; 7293 try 7294 { 7295 // the provided visual area should be used, if there is any 7296 if ( rVisArea.IsEmpty() ) 7297 { 7298 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ); 7299 Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit))); 7300 aAwtSz.Width = aSz.Width(); 7301 aAwtSz.Height = aSz.Height(); 7302 } 7303 else 7304 { 7305 aAwtSz.Width = rVisArea.GetWidth(); 7306 aAwtSz.Height = rVisArea.GetHeight(); 7307 } 7308 //xInplaceObj->EnableSetModified( sal_False ); 7309 xObj->setVisualAreaSize( nAspect, aAwtSz ); 7310 //xInplaceObj->EnableSetModified( sal_True );*/ 7311 } 7312 catch( uno::Exception& ) 7313 { 7314 OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" ); 7315 } 7316 } 7317 7318 svt::EmbeddedObjectRef aObj( xObj, nAspect ); 7319 7320 // TODO/LATER: need MediaType 7321 aObj.SetGraphic( rGrf, ::rtl::OUString() ); 7322 7323 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false); 7324 } 7325 } 7326 } 7327 7328 return pRet; 7329 } 7330 7331 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const 7332 { 7333 SdrObject* pRet = NULL; 7334 7335 if(120 >= sal_uInt16(eTyp)) 7336 { 7337 pRet = new SdrRectObj(); 7338 } 7339 7340 DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM"); 7341 7342 return pRet; 7343 } 7344 7345 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 7346 const String& rPropName, sal_Bool bTestPropertyAvailability ) 7347 { 7348 sal_Bool bRetValue = sal_True; 7349 if ( bTestPropertyAvailability ) 7350 { 7351 bRetValue = sal_False; 7352 try 7353 { 7354 uno::Reference< beans::XPropertySetInfo > 7355 aXPropSetInfo( rXPropSet->getPropertySetInfo() ); 7356 if ( aXPropSetInfo.is() ) 7357 bRetValue = aXPropSetInfo->hasPropertyByName( rPropName ); 7358 } 7359 catch( uno::Exception& ) 7360 { 7361 bRetValue = sal_False; 7362 } 7363 } 7364 if ( bRetValue ) 7365 { 7366 try 7367 { 7368 rXPropSet->setPropertyValue( rPropName, rAny ); 7369 bRetValue = sal_True; 7370 } 7371 catch( uno::Exception& ) 7372 { 7373 bRetValue = sal_False; 7374 } 7375 } 7376 return bRetValue; 7377 } 7378 7379 SvxMSDffImportRec::SvxMSDffImportRec() 7380 : pObj( 0 ), 7381 pWrapPolygon(0), 7382 pClientAnchorBuffer( 0 ), 7383 nClientAnchorLen( 0 ), 7384 pClientDataBuffer( 0 ), 7385 nClientDataLen( 0 ), 7386 nXAlign( 0 ), // position n cm from left 7387 nXRelTo( 2 ), // relative to column 7388 nYAlign( 0 ), // position n cm below 7389 nYRelTo( 2 ), // relative to paragraph 7390 nLayoutInTableCell( 0 ), // element is laid out in table cell 7391 nTextRotationAngle( 0 ), 7392 nDxTextLeft( 144 ), 7393 nDyTextTop( 72 ), 7394 nDxTextRight( 144 ), 7395 nDyTextBottom( 72 ), 7396 nDxWrapDistLeft( 0 ), 7397 nDyWrapDistTop( 0 ), 7398 nDxWrapDistRight( 0 ), 7399 nDyWrapDistBottom(0 ), 7400 nCropFromTop( 0 ), 7401 nCropFromBottom( 0 ), 7402 nCropFromLeft( 0 ), 7403 nCropFromRight( 0 ), 7404 aTextId( 0, 0 ), 7405 nNextShapeId( 0 ), 7406 nShapeId( 0 ), 7407 eShapeType( mso_sptNil ) 7408 { 7409 eLineStyle = mso_lineSimple; // GPF-Bug #66227# 7410 bDrawHell = sal_False; 7411 bHidden = sal_False; 7412 // bInGroup = sal_False; 7413 bReplaceByFly = sal_False; 7414 bLastBoxInChain = sal_True; 7415 bHasUDefProp = sal_False; // was the DFF_msofbtUDefProp record set? 7416 bVFlip = sal_False; 7417 bHFlip = sal_False; 7418 bAutoWidth = sal_False; 7419 } 7420 7421 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy) 7422 : pObj( rCopy.pObj ), 7423 nXAlign( rCopy.nXAlign ), 7424 nXRelTo( rCopy.nXRelTo ), 7425 nYAlign( rCopy.nYAlign ), 7426 nYRelTo( rCopy.nYRelTo ), 7427 nLayoutInTableCell( rCopy.nLayoutInTableCell ), 7428 nTextRotationAngle( rCopy.nTextRotationAngle ), 7429 nDxTextLeft( rCopy.nDxTextLeft ), 7430 nDyTextTop( rCopy.nDyTextTop ), 7431 nDxTextRight( rCopy.nDxTextRight ), 7432 nDyTextBottom( rCopy.nDyTextBottom ), 7433 nDxWrapDistLeft( rCopy.nDxWrapDistLeft ), 7434 nDyWrapDistTop( rCopy.nDyWrapDistTop ), 7435 nDxWrapDistRight( rCopy.nDxWrapDistRight ), 7436 nDyWrapDistBottom(rCopy.nDyWrapDistBottom ), 7437 nCropFromTop( rCopy.nCropFromTop ), 7438 nCropFromBottom( rCopy.nCropFromBottom ), 7439 nCropFromLeft( rCopy.nCropFromLeft ), 7440 nCropFromRight( rCopy.nCropFromRight ), 7441 aTextId( rCopy.aTextId ), 7442 nNextShapeId( rCopy.nNextShapeId ), 7443 nShapeId( rCopy.nShapeId ), 7444 eShapeType( rCopy.eShapeType ) 7445 { 7446 eLineStyle = rCopy.eLineStyle; // GPF-Bug #66227# 7447 bDrawHell = rCopy.bDrawHell; 7448 bHidden = rCopy.bHidden; 7449 // bInGroup = rCopy.bInGroup; 7450 bReplaceByFly = rCopy.bReplaceByFly; 7451 bAutoWidth = rCopy.bAutoWidth; 7452 bLastBoxInChain = rCopy.bLastBoxInChain; 7453 bHasUDefProp = rCopy.bHasUDefProp; 7454 bVFlip = rCopy.bVFlip; 7455 bHFlip = rCopy.bHFlip; 7456 nClientAnchorLen = rCopy.nClientAnchorLen; 7457 if( rCopy.nClientAnchorLen ) 7458 { 7459 pClientAnchorBuffer = new char[ nClientAnchorLen ]; 7460 memcpy( pClientAnchorBuffer, 7461 rCopy.pClientAnchorBuffer, 7462 nClientAnchorLen ); 7463 } 7464 else 7465 pClientAnchorBuffer = 0; 7466 7467 nClientDataLen = rCopy.nClientDataLen; 7468 if( rCopy.nClientDataLen ) 7469 { 7470 pClientDataBuffer = new char[ nClientDataLen ]; 7471 memcpy( pClientDataBuffer, 7472 rCopy.pClientDataBuffer, 7473 nClientDataLen ); 7474 } 7475 else 7476 pClientDataBuffer = 0; 7477 7478 if (rCopy.pWrapPolygon) 7479 pWrapPolygon = new Polygon(*rCopy.pWrapPolygon); 7480 else 7481 pWrapPolygon = 0; 7482 } 7483 7484 SvxMSDffImportRec::~SvxMSDffImportRec() 7485 { 7486 if (pClientAnchorBuffer) 7487 delete[] pClientAnchorBuffer; 7488 if (pClientDataBuffer) 7489 delete[] pClientDataBuffer; 7490 if (pWrapPolygon) 7491 delete pWrapPolygon; 7492 } 7493 7494 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 7495 7496 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape ) 7497 { 7498 maShapeIdContainer[nShapeId] = pShape; 7499 } 7500 7501 void SvxMSDffManager::removeShapeId( SdrObject* pShape ) 7502 { 7503 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() ); 7504 const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() ); 7505 while( aIter != aEnd ) 7506 { 7507 if( (*aIter).second == pShape ) 7508 { 7509 maShapeIdContainer.erase( aIter ); 7510 break; 7511 } 7512 aIter++; 7513 } 7514 } 7515 7516 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId ) 7517 { 7518 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) ); 7519 return aIter != maShapeIdContainer.end() ? (*aIter).second : 0; 7520 } 7521