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, 32768 )); 1998 double fOriginY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginY, (sal_uInt32)-32768 )); 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 & 0x1fff );//Last 13 bits for segment points number 2366 switch( nTmp >> 13 )//First 3 bits for command type 2367 { 2368 case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break; 2369 case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break; 2370 case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break; 2371 case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break; 2372 case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break; 2373 case 0x5: 2374 case 0x6: 2375 { 2376 switch ( ( nTmp >> 8 ) & 0x1f )//5 bits next to command type is for path escape type 2377 { 2378 case 0x0: 2379 { 2380 //It is msopathEscapeExtension which is transformed into LINETO. 2381 //If issue happens, I think this part can be comment so that it will be taken as unknow command. 2382 //When export, origin data will be export without any change. 2383 nCommand = EnhancedCustomShapeSegmentCommand::LINETO; 2384 if ( !nCnt ) 2385 nCnt = 1; 2386 } 2387 break; 2388 case 0x1: 2389 { 2390 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO; 2391 nCnt = ( nTmp & 0xff ) / 3; 2392 } 2393 break; 2394 case 0x2: 2395 { 2396 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE; 2397 nCnt = ( nTmp & 0xff ) / 3; 2398 } 2399 break; 2400 case 0x3: 2401 { 2402 nCommand = EnhancedCustomShapeSegmentCommand::ARCTO; 2403 nCnt = ( nTmp & 0xff ) >> 2; 2404 }; 2405 break; 2406 case 0x4: 2407 { 2408 nCommand = EnhancedCustomShapeSegmentCommand::ARC; 2409 nCnt = ( nTmp & 0xff ) >> 2; 2410 } 2411 break; 2412 case 0x5: 2413 { 2414 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO; 2415 nCnt = ( nTmp & 0xff ) >> 2; 2416 } 2417 break; 2418 case 0x6: 2419 { 2420 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC; 2421 nCnt = ( nTmp & 0xff ) >> 2; 2422 } 2423 break; 2424 case 0x7: 2425 { 2426 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX; 2427 nCnt = nTmp & 0xff; 2428 } 2429 break; 2430 case 0x8: 2431 { 2432 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY; 2433 nCnt = nTmp & 0xff; 2434 } 2435 break; 2436 case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break; 2437 case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break; 2438 } 2439 } 2440 break; 2441 } 2442 // if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss 2443 if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN ) 2444 nCnt = (sal_Int16)nTmp; 2445 aSegments[ i ].Command = nCommand; 2446 aSegments[ i ].Count = nCnt; 2447 } 2448 } 2449 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) ); 2450 aProp.Name = sSegments; 2451 aProp.Value <<= aSegments; 2452 aPathPropVec.push_back( aProp ); 2453 } 2454 // Path/StretchX 2455 if ( IsProperty( DFF_Prop_stretchPointX ) ) 2456 { 2457 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) ); 2458 sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 ); 2459 aProp.Name = sStretchX; 2460 aProp.Value <<= nStretchX; 2461 aPathPropVec.push_back( aProp ); 2462 } 2463 // Path/StretchX 2464 if ( IsProperty( DFF_Prop_stretchPointY ) ) 2465 { 2466 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) ); 2467 sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 ); 2468 aProp.Name = sStretchY; 2469 aProp.Value <<= nStretchY; 2470 aPathPropVec.push_back( aProp ); 2471 } 2472 // Path/TextFrames 2473 if ( IsProperty( DFF_Prop_textRectangles ) ) 2474 { 2475 sal_uInt16 i; 2476 sal_uInt16 nNumElem = 0; 2477 sal_uInt16 nNumElemMem = 0; 2478 sal_uInt16 nElemSize = 16; 2479 2480 if ( SeekToContent( DFF_Prop_textRectangles, rIn ) ) 2481 rIn >> nNumElem >> nNumElemMem >> nElemSize; 2482 if ( nElemSize == 16 ) 2483 { 2484 sal_Int32 nLeft, nTop, nRight, nBottom; 2485 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem ); 2486 for ( i = 0; i < nNumElem; i++ ) 2487 { 2488 rIn >> nLeft 2489 >> nTop 2490 >> nRight 2491 >> nBottom; 2492 2493 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First, nLeft ); 2494 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop ); 2495 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First, nRight ); 2496 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom); 2497 } 2498 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) ); 2499 aProp.Name = sTextFrames; 2500 aProp.Value <<= aTextFrames; 2501 aPathPropVec.push_back( aProp ); 2502 } 2503 } 2504 //Path/GluePoints 2505 if ( IsProperty( DFF_Prop_connectorPoints ) ) 2506 { 2507 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints; 2508 2509 sal_uInt16 i; 2510 sal_uInt16 nNumElemVert = 0; 2511 sal_uInt16 nNumElemMemVert = 0; 2512 sal_uInt16 nElemSizeVert = 8; 2513 2514 if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) ) 2515 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert; 2516 2517 sal_Int32 nX, nY; 2518 sal_Int16 nTmpA, nTmpB; 2519 aGluePoints.realloc( nNumElemVert ); 2520 for ( i = 0; i < nNumElemVert; i++ ) 2521 { 2522 if ( nElemSizeVert == 8 ) 2523 { 2524 rIn >> nX 2525 >> nY; 2526 } 2527 else 2528 { 2529 rIn >> nTmpA 2530 >> nTmpB; 2531 2532 nX = nTmpA; 2533 nY = nTmpB; 2534 } 2535 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First, nX ); 2536 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY ); 2537 } 2538 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) ); 2539 aProp.Name = sGluePoints; 2540 aProp.Value <<= aGluePoints; 2541 aPathPropVec.push_back( aProp ); 2542 } 2543 if ( IsProperty( DFF_Prop_connectorType ) ) 2544 { 2545 sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType ); 2546 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) ); 2547 aProp.Name = sGluePointType; 2548 aProp.Value <<= nGluePointType; 2549 aPathPropVec.push_back( aProp ); 2550 } 2551 // pushing the whole Path element 2552 if ( aPathPropVec.size() ) 2553 { 2554 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); 2555 PropSeq aPathPropSeq( aPathPropVec.size() ); 2556 aIter = aPathPropVec.begin(); 2557 aEnd = aPathPropVec.end(); 2558 beans::PropertyValue* pPathValues = aPathPropSeq.getArray(); 2559 while ( aIter != aEnd ) 2560 *pPathValues++ = *aIter++; 2561 aProp.Name = sPath; 2562 aProp.Value <<= aPathPropSeq; 2563 aPropVec.push_back( aProp ); 2564 } 2565 } 2566 ///////////////////////////////////////// 2567 // "TextPath" PropertySequence element // 2568 ///////////////////////////////////////// 2569 sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0; 2570 if ( bTextPathOn ) 2571 { 2572 PropVec aTextPathPropVec; 2573 2574 // TextPath 2575 const rtl::OUString sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); 2576 aProp.Name = sTextPathOn; 2577 aProp.Value <<= bTextPathOn; 2578 aTextPathPropVec.push_back( aProp ); 2579 2580 // TextPathMode 2581 const rtl::OUString sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) ); 2582 sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0; 2583 2584 sal_Bool bTextPathFitShape; 2585 if ( IsHardAttribute( DFF_Prop_gtextFStretch ) ) 2586 bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0; 2587 else 2588 { 2589 bTextPathFitShape = true; 2590 switch( rObjData.eShapeType ) 2591 { 2592 case mso_sptTextArchUpCurve : 2593 case mso_sptTextArchDownCurve : 2594 case mso_sptTextCircleCurve : 2595 case mso_sptTextButtonCurve : 2596 bTextPathFitShape = false; 2597 default : break; 2598 } 2599 } 2600 EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL ); 2601 if ( bTextPathFitShape ) 2602 eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE; 2603 else if ( bTextPathFitPath ) 2604 eTextPathMode = EnhancedCustomShapeTextPathMode_PATH; 2605 aProp.Name = sTextPathMode; 2606 aProp.Value <<= eTextPathMode; 2607 aTextPathPropVec.push_back( aProp ); 2608 2609 // ScaleX 2610 const rtl::OUString sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) ); 2611 sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0; 2612 aProp.Name = sTextPathScaleX; 2613 aProp.Value <<= bTextPathScaleX; 2614 aTextPathPropVec.push_back( aProp ); 2615 // SameLetterHeights 2616 const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) ); 2617 sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0; 2618 aProp.Name = sSameLetterHeight; 2619 aProp.Value <<= bSameLetterHeight; 2620 aTextPathPropVec.push_back( aProp ); 2621 2622 // pushing the whole TextPath element 2623 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); 2624 PropSeq aTextPathPropSeq( aTextPathPropVec.size() ); 2625 aIter = aTextPathPropVec.begin(); 2626 aEnd = aTextPathPropVec.end(); 2627 beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray(); 2628 while ( aIter != aEnd ) 2629 *pTextPathValues++ = *aIter++; 2630 aProp.Name = sTextPath; 2631 aProp.Value <<= aTextPathPropSeq; 2632 aPropVec.push_back( aProp ); 2633 } 2634 //////////////////////// 2635 // "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the 2636 //////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double 2637 2638 // checking the last used adjustment handle, so we can determine how many handles are to allocate 2639 sal_Int32 i = DFF_Prop_adjust10Value; 2640 while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) ) 2641 i--; 2642 sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1; 2643 if ( nAdjustmentValues ) 2644 { 2645 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues ); 2646 while( --nAdjustmentValues >= 0 ) 2647 { 2648 sal_Int32 nValue = 0; 2649 beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE; 2650 if ( IsProperty( i ) ) 2651 { 2652 nValue = GetPropertyValue( i ); 2653 ePropertyState = beans::PropertyState_DIRECT_VALUE; 2654 } 2655 if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) ) 2656 { 2657 double fValue = nValue; 2658 fValue /= 65536; 2659 aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue; 2660 } 2661 else 2662 aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue; 2663 aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState; 2664 i--; 2665 } 2666 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); 2667 aProp.Name = sAdjustmentValues; 2668 aProp.Value <<= aAdjustmentSeq; 2669 aPropVec.push_back( aProp ); 2670 } 2671 2672 // creating the whole property set 2673 PropSeq aSeq( aPropVec.size() ); 2674 beans::PropertyValue* pValues = aSeq.getArray(); 2675 aIter = aPropVec.begin(); 2676 aEnd = aPropVec.end(); 2677 while ( aIter != aEnd ) 2678 *pValues++ = *aIter++; 2679 rSet.Put( SdrCustomShapeGeometryItem( aSeq ) ); 2680 } 2681 2682 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const 2683 { 2684 Rectangle aEmptyRect; 2685 DffRecordHeader aHdTemp; 2686 DffObjData aDffObjTemp( aHdTemp, aEmptyRect, 0 ); 2687 ApplyAttributes( rIn, rSet, aDffObjTemp ); 2688 } 2689 2690 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const 2691 { 2692 sal_Bool bHasShadow = sal_False; 2693 if ( IsProperty( DFF_Prop_gtextSize ) ) 2694 rSet.Put( SvxFontHeightItem( rManager.ScalePt( GetPropertyValue( DFF_Prop_gtextSize ) ), 100, EE_CHAR_FONTHEIGHT ) ); 2695 sal_uInt32 nFontAttributes = GetPropertyValue( DFF_Prop_gtextFStrikethrough ); 2696 if ( nFontAttributes & 0x20 ) 2697 rSet.Put( SvxWeightItem( nFontAttributes & 0x20 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); 2698 if ( nFontAttributes & 0x10 ) 2699 rSet.Put( SvxPostureItem( nFontAttributes & 0x10 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) ); 2700 if ( nFontAttributes & 0x08 ) 2701 rSet.Put( SvxUnderlineItem( nFontAttributes & 0x08 ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) ); 2702 if ( nFontAttributes & 0x40 ) 2703 rSet.Put( SvxShadowedItem( nFontAttributes & 0x40 != 0, EE_CHAR_SHADOW ) ); 2704 // if ( nFontAttributes & 0x02 ) 2705 // rSet.Put( SvxCaseMapItem( nFontAttributes & 0x02 ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) ); 2706 if ( nFontAttributes & 0x01 ) 2707 rSet.Put( SvxCrossedOutItem( nFontAttributes & 0x01 ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) ); 2708 if ( IsProperty( DFF_Prop_fillColor ) ) 2709 rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor ) ) ); 2710 if ( IsProperty( DFF_Prop_shadowType ) ) 2711 { 2712 MSO_ShadowType eShadowType = static_cast< MSO_ShadowType >( GetPropertyValue( DFF_Prop_shadowType ) ); 2713 if( eShadowType != mso_shadowOffset ) 2714 { 2715 rSet.Put( SdrShadowXDistItem( 35 ) ); // 0,35 mm Schattendistanz 2716 rSet.Put( SdrShadowYDistItem( 35 ) ); 2717 } 2718 } 2719 if ( IsProperty( DFF_Prop_shadowColor ) ) 2720 rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_shadowColor ), DFF_Prop_shadowColor ) ) ); 2721 if ( IsProperty( DFF_Prop_shadowOpacity ) ) 2722 rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - GetPropertyValue( DFF_Prop_shadowOpacity ) ) / 655 ) ) ); 2723 if ( IsProperty( DFF_Prop_shadowOffsetX ) ) 2724 { 2725 sal_Int32 nVal = static_cast< sal_Int32 >( GetPropertyValue( DFF_Prop_shadowOffsetX ) ); 2726 rManager.ScaleEmu( 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 rSet.Put( SdrShadowYDistItem( nVal ) ); 2734 } 2735 if ( IsProperty( DFF_Prop_fshadowObscured ) ) 2736 { 2737 bHasShadow = ( GetPropertyValue( DFF_Prop_fshadowObscured ) & 2 ) != 0; 2738 if ( bHasShadow ) 2739 { 2740 if ( !IsProperty( DFF_Prop_shadowOffsetX ) ) 2741 rSet.Put( SdrShadowXDistItem( 35 ) ); 2742 if ( !IsProperty( DFF_Prop_shadowOffsetY ) ) 2743 rSet.Put( SdrShadowYDistItem( 35 ) ); 2744 } 2745 } 2746 if ( bHasShadow ) 2747 { 2748 // #160376# sj: activating shadow only if fill and or linestyle is used 2749 // this is required because of the latest drawing layer core changes. 2750 // Issue i104085 is related to this. 2751 sal_uInt32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash )); 2752 if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( rObjData.eShapeType )) 2753 nLineFlags &= ~0x08; 2754 sal_uInt32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest )); 2755 if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType )) 2756 nFillFlags &= ~0x10; 2757 if ( nFillFlags & 0x10 ) 2758 { 2759 MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid ); 2760 switch( eMSO_FillType ) 2761 { 2762 case mso_fillSolid : 2763 case mso_fillPattern : 2764 case mso_fillTexture : 2765 case mso_fillPicture : 2766 case mso_fillShade : 2767 case mso_fillShadeCenter : 2768 case mso_fillShadeShape : 2769 case mso_fillShadeScale : 2770 case mso_fillShadeTitle : 2771 break; 2772 // case mso_fillBackground : 2773 default: 2774 nFillFlags &=~0x10; // no fillstyle used 2775 break; 2776 } 2777 } 2778 if ( ( ( nLineFlags & 0x08 ) == 0 ) && ( ( nFillFlags & 0x10 ) == 0 ) ) // if there is no fillstyle and linestyle 2779 bHasShadow = sal_False; // we are turning shadow off. 2780 2781 if ( bHasShadow ) 2782 rSet.Put( SdrShadowItem( bHasShadow ) ); 2783 } 2784 ApplyLineAttributes( rSet, rObjData.eShapeType ); // #i28269# 2785 ApplyFillAttributes( rIn, rSet, rObjData ); 2786 if ( rObjData.eShapeType != mso_sptNil || IsProperty( DFF_Prop_pVertices ) ) 2787 { 2788 ApplyCustomShapeGeometryAttributes( rIn, rSet, rObjData ); 2789 ApplyCustomShapeTextAttributes( rSet ); 2790 if ( rManager.GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL ) 2791 { 2792 if ( mnFix16Angle || ( rObjData.nSpFlags & SP_FFLIPV ) ) 2793 CheckAndCorrectExcelTextRotation( rIn, rSet, rObjData ); 2794 } 2795 } 2796 } 2797 2798 void DffPropertyReader::CheckAndCorrectExcelTextRotation( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const 2799 { 2800 sal_Bool bRotateTextWithShape = rObjData.bRotateTextWithShape; 2801 if ( rObjData.bOpt2 ) // sj: #158494# is the second property set available ? if then we have to check the xml data of 2802 { // the shape, because the textrotation of Excel 2003 and greater versions is stored there 2803 // (upright property of the textbox) 2804 if ( rManager.pSecPropSet->SeekToContent( DFF_Prop_metroBlob, rIn ) ) 2805 { 2806 sal_uInt32 nLen = rManager.pSecPropSet->GetPropertyValue( DFF_Prop_metroBlob ); 2807 if ( nLen ) 2808 { 2809 ::com::sun::star::uno::Sequence< sal_Int8 > aXMLDataSeq( nLen ); 2810 rIn.Read( aXMLDataSeq.getArray(), nLen ); 2811 ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInputStream 2812 ( new ::comphelper::SequenceInputStream( aXMLDataSeq ) ); 2813 try 2814 { 2815 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); 2816 if ( xFactory.is() ) 2817 { 2818 ::com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage 2819 ( ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( 2820 OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xFactory, sal_True ) ); 2821 if ( xStorage.is() ) 2822 { 2823 const rtl::OUString sDRS( RTL_CONSTASCII_USTRINGPARAM ( "drs" ) ); 2824 ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > 2825 xStorageDRS( xStorage->openStorageElement( sDRS, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) ); 2826 if ( xStorageDRS.is() ) 2827 { 2828 const rtl::OUString sShapeXML( RTL_CONSTASCII_USTRINGPARAM ( "shapexml.xml" ) ); 2829 ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xShapeXMLStream( xStorageDRS->openStreamElement( sShapeXML, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) ); 2830 if ( xShapeXMLStream.is() ) 2831 { 2832 ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xShapeXMLInputStream( xShapeXMLStream->getInputStream() ); 2833 if ( xShapeXMLInputStream.is() ) 2834 { 2835 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; 2836 sal_Int32 nBytesRead = xShapeXMLInputStream->readBytes( aSeq, 0x7fffffff ); 2837 if ( nBytesRead ) 2838 { // for only one property I spare to use a XML parser at this point, this 2839 // should be enhanced if needed 2840 2841 bRotateTextWithShape = sal_True; // using the correct xml default 2842 const char* pArry = reinterpret_cast< char* >( aSeq.getArray() ); 2843 const char* pUpright = "upright="; 2844 const char* pEnd = pArry + nBytesRead; 2845 const char* pPtr = pArry; 2846 while( ( pPtr + 12 ) < pEnd ) 2847 { 2848 if ( !memcmp( pUpright, pPtr, 8 ) ) 2849 { 2850 bRotateTextWithShape = ( pPtr[ 9 ] != '1' ) && ( pPtr[ 9 ] != 't' ); 2851 break; 2852 } 2853 else 2854 pPtr++; 2855 } 2856 } 2857 } 2858 } 2859 } 2860 } 2861 } 2862 } 2863 catch( com::sun::star::uno::Exception& ) 2864 { 2865 } 2866 } 2867 } 2868 } 2869 if ( !bRotateTextWithShape ) 2870 { 2871 const com::sun::star::uno::Any* pAny, aAny; 2872 SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)rSet.Get( SDRATTR_CUSTOMSHAPE_GEOMETRY )); 2873 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) ); 2874 pAny = aGeometryItem.GetPropertyValueByName( sTextRotateAngle ); 2875 double fExtraTextRotateAngle = 0.0; 2876 if ( pAny ) 2877 *pAny >>= fExtraTextRotateAngle; 2878 2879 if ( rManager.mnFix16Angle ) 2880 fExtraTextRotateAngle += mnFix16Angle / 100.0; 2881 if ( rObjData.nSpFlags & SP_FFLIPV ) 2882 fExtraTextRotateAngle -= 180.0; 2883 2884 com::sun::star::beans::PropertyValue aTextRotateAngle; 2885 aTextRotateAngle.Name = sTextRotateAngle; 2886 aTextRotateAngle.Value <<= fExtraTextRotateAngle; 2887 aGeometryItem.SetPropertyValue( aTextRotateAngle ); 2888 rSet.Put( aGeometryItem ); 2889 } 2890 } 2891 2892 //--------------------------------------------------------------------------- 2893 //- Record Manager ---------------------------------------------------------- 2894 //--------------------------------------------------------------------------- 2895 2896 DffRecordList::DffRecordList( DffRecordList* pList ) : 2897 nCount ( 0 ), 2898 nCurrent ( 0 ), 2899 pPrev ( pList ), 2900 pNext ( NULL ) 2901 { 2902 if ( pList ) 2903 pList->pNext = this; 2904 } 2905 2906 DffRecordList::~DffRecordList() 2907 { 2908 delete pNext; 2909 } 2910 2911 DffRecordManager::DffRecordManager() : 2912 DffRecordList ( NULL ), 2913 pCList ( (DffRecordList*)this ) 2914 { 2915 } 2916 2917 DffRecordManager::DffRecordManager( SvStream& rIn ) : 2918 DffRecordList ( NULL ), 2919 pCList ( (DffRecordList*)this ) 2920 { 2921 Consume( rIn ); 2922 } 2923 2924 DffRecordManager::~DffRecordManager() 2925 { 2926 }; 2927 2928 2929 void DffRecordManager::Consume( SvStream& rIn, sal_Bool bAppend, sal_uInt32 nStOfs ) 2930 { 2931 if ( !bAppend ) 2932 Clear(); 2933 sal_uInt32 nOldPos = rIn.Tell(); 2934 if ( !nStOfs ) 2935 { 2936 DffRecordHeader aHd; 2937 rIn >> aHd; 2938 if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER ) 2939 nStOfs = aHd.GetRecEndFilePos(); 2940 } 2941 if ( nStOfs ) 2942 { 2943 pCList = (DffRecordList*)this; 2944 while ( pCList->pNext ) 2945 pCList = pCList->pNext; 2946 while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <= nStOfs ) ) 2947 { 2948 if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE ) 2949 pCList = new DffRecordList( pCList ); 2950 rIn >> pCList->mHd[ pCList->nCount ]; 2951 pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn ); 2952 } 2953 rIn.Seek( nOldPos ); 2954 } 2955 } 2956 2957 void DffRecordManager::Clear() 2958 { 2959 pCList = (DffRecordList*)this; 2960 delete pNext, pNext = NULL; 2961 nCurrent = 0; 2962 nCount = 0; 2963 } 2964 2965 DffRecordHeader* DffRecordManager::Current() 2966 { 2967 DffRecordHeader* pRet = NULL; 2968 if ( pCList->nCurrent < pCList->nCount ) 2969 pRet = &pCList->mHd[ pCList->nCurrent ]; 2970 return pRet; 2971 } 2972 2973 DffRecordHeader* DffRecordManager::First() 2974 { 2975 DffRecordHeader* pRet = NULL; 2976 pCList = (DffRecordList*)this; 2977 if ( pCList->nCount ) 2978 { 2979 pCList->nCurrent = 0; 2980 pRet = &pCList->mHd[ 0 ]; 2981 } 2982 return pRet; 2983 } 2984 2985 DffRecordHeader* DffRecordManager::Next() 2986 { 2987 DffRecordHeader* pRet = NULL; 2988 sal_uInt32 nC = pCList->nCurrent + 1; 2989 if ( nC < pCList->nCount ) 2990 { 2991 pCList->nCurrent++; 2992 pRet = &pCList->mHd[ nC ]; 2993 } 2994 else if ( pCList->pNext ) 2995 { 2996 pCList = pCList->pNext; 2997 pCList->nCurrent = 0; 2998 pRet = &pCList->mHd[ 0 ]; 2999 } 3000 return pRet; 3001 } 3002 3003 DffRecordHeader* DffRecordManager::Prev() 3004 { 3005 DffRecordHeader* pRet = NULL; 3006 sal_uInt32 nCur = pCList->nCurrent; 3007 if ( !nCur && pCList->pPrev ) 3008 { 3009 pCList = pCList->pPrev; 3010 nCur = pCList->nCount; 3011 } 3012 if ( nCur-- ) 3013 { 3014 pCList->nCurrent = nCur; 3015 pRet = &pCList->mHd[ nCur ]; 3016 } 3017 return pRet; 3018 } 3019 3020 DffRecordHeader* DffRecordManager::Last() 3021 { 3022 DffRecordHeader* pRet = NULL; 3023 while ( pCList->pNext ) 3024 pCList = pCList->pNext; 3025 sal_uInt32 nCnt = pCList->nCount; 3026 if ( nCnt-- ) 3027 { 3028 pCList->nCurrent = nCnt; 3029 pRet = &pCList->mHd[ nCnt ]; 3030 } 3031 return pRet; 3032 } 3033 3034 sal_Bool DffRecordManager::SeekToContent( SvStream& rIn, sal_uInt16 nRecId, DffSeekToContentMode eMode ) 3035 { 3036 DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode ); 3037 if ( pHd ) 3038 { 3039 pHd->SeekToContent( rIn ); 3040 return sal_True; 3041 } 3042 else 3043 return sal_False; 3044 } 3045 3046 DffRecordHeader* DffRecordManager::GetRecordHeader( sal_uInt16 nRecId, DffSeekToContentMode eMode ) 3047 { 3048 sal_uInt32 nOldCurrent = pCList->nCurrent; 3049 DffRecordList* pOldList = pCList; 3050 DffRecordHeader* pHd; 3051 3052 if ( eMode == SEEK_FROM_BEGINNING ) 3053 pHd = First(); 3054 else 3055 pHd = Next(); 3056 3057 while ( pHd ) 3058 { 3059 if ( pHd->nRecType == nRecId ) 3060 break; 3061 pHd = Next(); 3062 } 3063 if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART ) 3064 { 3065 DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ]; 3066 pHd = First(); 3067 if ( pHd ) 3068 { 3069 while ( pHd != pBreak ) 3070 { 3071 if ( pHd->nRecType == nRecId ) 3072 break; 3073 pHd = Next(); 3074 } 3075 if ( pHd->nRecType != nRecId ) 3076 pHd = NULL; 3077 } 3078 } 3079 if ( !pHd ) 3080 { 3081 pCList = pOldList; 3082 pOldList->nCurrent = nOldCurrent; 3083 } 3084 return pHd; 3085 } 3086 3087 //--------------------------------------------------------------------------- 3088 // private Methoden 3089 //--------------------------------------------------------------------------- 3090 3091 struct EscherBlipCacheEntry 3092 { 3093 ByteString aUniqueID; 3094 sal_uInt32 nBlip; 3095 3096 EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) : 3097 aUniqueID( rUniqueID ), 3098 nBlip( nBlipId ) {} 3099 }; 3100 3101 void SvxMSDffManager::Scale( sal_Int32& rVal ) const 3102 { 3103 if ( bNeedMap ) 3104 rVal = BigMulDiv( rVal, nMapMul, nMapDiv ); 3105 } 3106 3107 void SvxMSDffManager::Scale( Point& rPos ) const 3108 { 3109 rPos.X() += nMapXOfs; 3110 rPos.Y() += nMapYOfs; 3111 if ( bNeedMap ) 3112 { 3113 rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv ); 3114 rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv ); 3115 } 3116 } 3117 3118 void SvxMSDffManager::Scale( Size& rSiz ) const 3119 { 3120 if ( bNeedMap ) 3121 { 3122 rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv ); 3123 rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv ); 3124 } 3125 } 3126 3127 void SvxMSDffManager::Scale( Rectangle& rRect ) const 3128 { 3129 rRect.Move( nMapXOfs, nMapYOfs ); 3130 if ( bNeedMap ) 3131 { 3132 rRect.Left() =BigMulDiv( rRect.Left() , nMapMul, nMapDiv ); 3133 rRect.Top() =BigMulDiv( rRect.Top() , nMapMul, nMapDiv ); 3134 rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv ); 3135 rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv ); 3136 } 3137 } 3138 3139 void SvxMSDffManager::Scale( Polygon& rPoly ) const 3140 { 3141 if ( !bNeedMap ) 3142 return; 3143 sal_uInt16 nPointAnz = rPoly.GetSize(); 3144 for ( sal_uInt16 nPointNum = 0; nPointNum < nPointAnz; nPointNum++ ) 3145 Scale( rPoly[ nPointNum ] ); 3146 } 3147 3148 void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const 3149 { 3150 if ( !bNeedMap ) 3151 return; 3152 sal_uInt16 nPolyAnz = rPoly.Count(); 3153 for ( sal_uInt16 nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ ) 3154 Scale( rPoly[ nPolyNum ] ); 3155 } 3156 3157 void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const 3158 { 3159 rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv ); 3160 } 3161 3162 sal_uInt32 SvxMSDffManager::ScalePt( sal_uInt32 nVal ) const 3163 { 3164 MapUnit eMap = pSdrModel->GetScaleUnit(); 3165 Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() ); 3166 long aMul = aFact.GetNumerator(); 3167 long aDiv = aFact.GetDenominator() * 65536; 3168 aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen 3169 return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() ); 3170 } 3171 3172 sal_Int32 SvxMSDffManager::ScalePoint( sal_Int32 nVal ) const 3173 { 3174 return BigMulDiv( nVal, nPntMul, nPntDiv ); 3175 }; 3176 3177 void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale) 3178 { 3179 pSdrModel = pModel; 3180 if( pModel && (0 < nApplicationScale) ) 3181 { 3182 // PPT arbeitet nur mit Einheiten zu 576DPI 3183 // WW hingegen verwendet twips, dh. 1440DPI. 3184 MapUnit eMap = pSdrModel->GetScaleUnit(); 3185 Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() ); 3186 long nMul=aFact.GetNumerator(); 3187 long nDiv=aFact.GetDenominator()*nApplicationScale; 3188 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen 3189 // Bei 100TH_MM -> 2540/576=635/144 3190 // Bei Twip -> 1440/576=5/2 3191 nMapMul = aFact.GetNumerator(); 3192 nMapDiv = aFact.GetDenominator(); 3193 bNeedMap = nMapMul!=nMapDiv; 3194 3195 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben 3196 // 1mm=36000emu, 1twip=635emu 3197 aFact=GetMapFactor(MAP_100TH_MM,eMap).X(); 3198 nMul=aFact.GetNumerator(); 3199 nDiv=aFact.GetDenominator()*360; 3200 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen 3201 // Bei 100TH_MM -> 1/360 3202 // Bei Twip -> 14,40/(25,4*360)=144/91440=1/635 3203 nEmuMul=aFact.GetNumerator(); 3204 nEmuDiv=aFact.GetDenominator(); 3205 3206 // Und noch was fuer typografische Points 3207 aFact=GetMapFactor(MAP_POINT,eMap).X(); 3208 nPntMul=aFact.GetNumerator(); 3209 nPntDiv=aFact.GetDenominator(); 3210 } 3211 else 3212 { 3213 pModel = 0; 3214 nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0; 3215 bNeedMap = sal_False; 3216 } 3217 } 3218 3219 sal_Bool SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, sal_uInt32 nId ) const 3220 { 3221 sal_Bool bRet = sal_False; 3222 if ( mpFidcls ) 3223 { 3224 sal_uInt32 nMerk = rSt.Tell(); 3225 sal_uInt32 nShapeId, nSec = ( nId >> 10 ) - 1; 3226 if ( nSec < mnIdClusters ) 3227 { 3228 sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid ); 3229 if ( nOfs ) 3230 { 3231 rSt.Seek( nOfs ); 3232 DffRecordHeader aEscherF002Hd; 3233 rSt >> aEscherF002Hd; 3234 sal_uLong nEscherF002End = aEscherF002Hd.GetRecEndFilePos(); 3235 DffRecordHeader aEscherObjListHd; 3236 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nEscherF002End ) ) 3237 { 3238 rSt >> aEscherObjListHd; 3239 if ( aEscherObjListHd.nRecVer != 0xf ) 3240 aEscherObjListHd.SeekToEndOfRecord( rSt ); 3241 else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer ) 3242 { 3243 DffRecordHeader aShapeHd; 3244 if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) ) 3245 { 3246 rSt >> nShapeId; 3247 if ( nId == nShapeId ) 3248 { 3249 aEscherObjListHd.SeekToBegOfRecord( rSt ); 3250 bRet = sal_True; 3251 break; 3252 } 3253 } 3254 aEscherObjListHd.SeekToEndOfRecord( rSt ); 3255 } 3256 } 3257 } 3258 } 3259 if ( !bRet ) 3260 rSt.Seek( nMerk ); 3261 } 3262 return bRet; 3263 } 3264 3265 FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, sal_uInt16 nRecId, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const 3266 { 3267 FASTBOOL bRet = sal_False; 3268 sal_uLong nFPosMerk = rSt.Tell(); // store FilePos to restore it later if necessary 3269 DffRecordHeader aHd; 3270 do 3271 { 3272 rSt >> aHd; 3273 3274 // check potential error reading and if seeking to the end of record is possible at all. 3275 // It is probably cheaper instead of doing the file seek operation 3276 if ( rSt.GetError() || ( aHd.GetRecEndFilePos() > nMaxFilePos ) ) 3277 { 3278 bRet= sal_False; 3279 break; 3280 } 3281 3282 if ( aHd.nRecType == nRecId ) 3283 { 3284 if ( nSkipCount ) 3285 nSkipCount--; 3286 else 3287 { 3288 bRet = sal_True; 3289 if ( pRecHd != NULL ) 3290 *pRecHd = aHd; 3291 else 3292 aHd.SeekToBegOfRecord( rSt ); 3293 } 3294 } 3295 if ( !bRet ) 3296 aHd.SeekToEndOfRecord( rSt ); 3297 } 3298 while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet ); 3299 if ( !bRet ) 3300 rSt.Seek( nFPosMerk ); // restore orginal FilePos 3301 return bRet; 3302 } 3303 3304 FASTBOOL SvxMSDffManager::SeekToRec2( sal_uInt16 nRecId1, sal_uInt16 nRecId2, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const 3305 { 3306 FASTBOOL bRet = sal_False; 3307 sal_uLong nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer ggf. spaetere Restauration 3308 DffRecordHeader aHd; 3309 do 3310 { 3311 rStCtrl >> aHd; 3312 if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 ) 3313 { 3314 if ( nSkipCount ) 3315 nSkipCount--; 3316 else 3317 { 3318 bRet = sal_True; 3319 if ( pRecHd ) 3320 *pRecHd = aHd; 3321 else 3322 aHd.SeekToBegOfRecord( rStCtrl ); 3323 } 3324 } 3325 if ( !bRet ) 3326 aHd.SeekToEndOfRecord( rStCtrl ); 3327 } 3328 while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet ); 3329 if ( !bRet ) 3330 rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren 3331 return bRet; 3332 } 3333 3334 3335 FASTBOOL SvxMSDffManager::GetColorFromPalette( sal_uInt16 /* nNum */, Color& rColor ) const 3336 { 3337 // diese Methode ist in der zum Excel-Import 3338 // abgeleiteten Klasse zu ueberschreiben... 3339 rColor.SetColor( COL_WHITE ); 3340 return sal_True; 3341 } 3342 3343 // sj: the documentation is not complete, especially in ppt the normal rgb for text 3344 // color is written as 0xfeRRGGBB, this can't be explained by the documentation, nearly 3345 // every bit in the upper code is set -> so there seems to be a special handling for 3346 // ppt text colors, i decided not to fix this in MSO_CLR_ToColor because of possible 3347 // side effects, instead MSO_TEXT_CLR_ToColor is called for PPT text colors, to map 3348 // the color code to something that behaves like the other standard color codes used by 3349 // fill and line color 3350 Color SvxMSDffManager::MSO_TEXT_CLR_ToColor( sal_uInt32 nColorCode ) const 3351 { 3352 // Fuer Textfarben: Header ist 0xfeRRGGBB 3353 if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 ) 3354 nColorCode &= 0x00ffffff; 3355 else 3356 { 3357 // for colorscheme colors the color index are the lower three bits of the upper byte 3358 if ( ( nColorCode & 0xf8000000 ) == 0 ) // this must be a colorscheme index 3359 { 3360 nColorCode >>= 24; 3361 nColorCode |= 0x8000000; 3362 } 3363 } 3364 return MSO_CLR_ToColor( nColorCode ); 3365 } 3366 3367 Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const 3368 { 3369 Color aColor( mnDefaultColor ); 3370 3371 // Fuer Textfarben: Header ist 0xfeRRGGBB 3372 if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 ) // sj: it needs to be checked if 0xfe is used in 3373 nColorCode &= 0x00ffffff; // other cases than ppt text -> if not this code can be removed 3374 3375 sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 ); 3376 3377 // sj: below change from 0x1b to 0x19 was done because of i84812 (0x02 -> rgb color), 3378 // now I have some problems to fix i104685 (there the color value is 0x02000000 whichs requires 3379 // a 0x2 scheme color to be displayed properly), the color docu seems to be incomplete 3380 if( nUpper & 0x19 ) // if( nUpper & 0x1f ) 3381 { 3382 if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) ) 3383 { 3384 // SCHEMECOLOR 3385 if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) ) 3386 { 3387 switch( nContentProperty ) 3388 { 3389 case DFF_Prop_pictureTransparent : 3390 case DFF_Prop_shadowColor : 3391 case DFF_Prop_fillBackColor : 3392 case DFF_Prop_fillColor : 3393 aColor = Color( COL_WHITE ); 3394 break; 3395 case DFF_Prop_lineColor : 3396 { 3397 aColor = Color( COL_BLACK ); 3398 } 3399 break; 3400 } 3401 } 3402 } 3403 else // SYSCOLOR 3404 { 3405 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 3406 3407 // sal_uInt16 nParameter = (sal_uInt8)( nColorCode >> 16); // SJ: nice compiler optimization bug on windows, though downcasting 3408 sal_uInt16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o 3409 sal_uInt16 nFunctionBits = (sal_uInt16)( ( nColorCode & 0x00000f00 ) >> 8 ); 3410 sal_uInt16 nAdditionalFlags = (sal_uInt16)( ( nColorCode & 0x0000f000) >> 8 ); 3411 sal_uInt16 nColorIndex = sal_uInt16(nColorCode & 0x00ff); 3412 sal_uInt32 nPropColor = 0; 3413 3414 sal_uInt16 nCProp = 0; 3415 3416 switch ( nColorIndex ) 3417 { 3418 case mso_syscolorButtonFace : aColor = rStyleSettings.GetFaceColor(); break; 3419 case mso_syscolorWindowText : aColor = rStyleSettings.GetWindowTextColor(); break; 3420 case mso_syscolorMenu : aColor = rStyleSettings.GetMenuColor(); break; 3421 case mso_syscolor3DLight : 3422 case mso_syscolorButtonHighlight : 3423 case mso_syscolorHighlight : aColor = rStyleSettings.GetHighlightColor(); break; 3424 case mso_syscolorHighlightText : aColor = rStyleSettings.GetHighlightTextColor(); break; 3425 case mso_syscolorCaptionText : aColor = rStyleSettings.GetMenuTextColor(); break; 3426 case mso_syscolorActiveCaption : aColor = rStyleSettings.GetHighlightColor(); break; 3427 case mso_syscolorButtonShadow : aColor = rStyleSettings.GetShadowColor(); break; 3428 case mso_syscolorButtonText : aColor = rStyleSettings.GetButtonTextColor(); break; 3429 case mso_syscolorGrayText : aColor = rStyleSettings.GetDeactiveColor(); break; 3430 case mso_syscolorInactiveCaption : aColor = rStyleSettings.GetDeactiveColor(); break; 3431 case mso_syscolorInactiveCaptionText : aColor = rStyleSettings.GetDeactiveColor(); break; 3432 case mso_syscolorInfoBackground : aColor = rStyleSettings.GetFaceColor(); break; 3433 case mso_syscolorInfoText : aColor = rStyleSettings.GetInfoTextColor(); break; 3434 case mso_syscolorMenuText : aColor = rStyleSettings.GetMenuTextColor(); break; 3435 case mso_syscolorScrollbar : aColor = rStyleSettings.GetFaceColor(); break; 3436 case mso_syscolorWindow : aColor = rStyleSettings.GetWindowColor(); break; 3437 case mso_syscolorWindowFrame : aColor = rStyleSettings.GetWindowColor(); break; 3438 3439 case mso_colorFillColor : 3440 { 3441 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); 3442 nCProp = DFF_Prop_fillColor; 3443 } 3444 break; 3445 case mso_colorLineOrFillColor : // ( use the line color only if there is a line ) 3446 { 3447 if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 ) 3448 { 3449 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 ); 3450 nCProp = DFF_Prop_lineColor; 3451 } 3452 else 3453 { 3454 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); 3455 nCProp = DFF_Prop_fillColor; 3456 } 3457 } 3458 break; 3459 case mso_colorLineColor : 3460 { 3461 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 ); 3462 nCProp = DFF_Prop_lineColor; 3463 } 3464 break; 3465 case mso_colorShadowColor : 3466 { 3467 nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 ); 3468 nCProp = DFF_Prop_shadowColor; 3469 } 3470 break; 3471 case mso_colorThis : // ( use this color ... ) 3472 { 3473 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //????????????? 3474 nCProp = DFF_Prop_fillColor; 3475 } 3476 break; 3477 case mso_colorFillBackColor : 3478 { 3479 nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff ); 3480 nCProp = DFF_Prop_fillBackColor; 3481 } 3482 break; 3483 case mso_colorLineBackColor : 3484 { 3485 nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff ); 3486 nCProp = DFF_Prop_lineBackColor; 3487 } 3488 break; 3489 case mso_colorFillThenLine : // ( use the fillcolor unless no fill and line ) 3490 { 3491 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //????????????? 3492 nCProp = DFF_Prop_fillColor; 3493 } 3494 break; 3495 case mso_colorIndexMask : // ( extract the color index ) ? 3496 { 3497 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //????????????? 3498 nCProp = DFF_Prop_fillColor; 3499 } 3500 break; 3501 } 3502 if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive 3503 aColor = MSO_CLR_ToColor( nPropColor, nCProp ); 3504 3505 if( nAdditionalFlags & 0x80 ) // make color gray 3506 { 3507 sal_uInt8 nZwi = aColor.GetLuminance(); 3508 aColor = Color( nZwi, nZwi, nZwi ); 3509 } 3510 switch( nFunctionBits ) 3511 { 3512 case 0x01 : // darken color by parameter 3513 { 3514 aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetRed() ) >> 8 ) ); 3515 aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) ); 3516 aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) ); 3517 } 3518 break; 3519 case 0x02 : // lighten color by parameter 3520 { 3521 sal_uInt16 nInvParameter = ( 0x00ff - nParameter ) * 0xff; 3522 aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) ); 3523 aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) ); 3524 aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) ); 3525 } 3526 break; 3527 case 0x03 : // add grey level RGB(p,p,p) 3528 { 3529 sal_Int16 nR = (sal_Int16)aColor.GetRed() + (sal_Int16)nParameter; 3530 sal_Int16 nG = (sal_Int16)aColor.GetGreen() + (sal_Int16)nParameter; 3531 sal_Int16 nB = (sal_Int16)aColor.GetBlue() + (sal_Int16)nParameter; 3532 if ( nR > 0x00ff ) 3533 nR = 0x00ff; 3534 if ( nG > 0x00ff ) 3535 nG = 0x00ff; 3536 if ( nB > 0x00ff ) 3537 nB = 0x00ff; 3538 aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB ); 3539 } 3540 break; 3541 case 0x04 : // substract grey level RGB(p,p,p) 3542 { 3543 sal_Int16 nR = (sal_Int16)aColor.GetRed() - (sal_Int16)nParameter; 3544 sal_Int16 nG = (sal_Int16)aColor.GetGreen() - (sal_Int16)nParameter; 3545 sal_Int16 nB = (sal_Int16)aColor.GetBlue() - (sal_Int16)nParameter; 3546 if ( nR < 0 ) 3547 nR = 0; 3548 if ( nG < 0 ) 3549 nG = 0; 3550 if ( nB < 0 ) 3551 nB = 0; 3552 aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB ); 3553 } 3554 break; 3555 case 0x05 : // substract from grey level RGB(p,p,p) 3556 { 3557 sal_Int16 nR = (sal_Int16)nParameter - (sal_Int16)aColor.GetRed(); 3558 sal_Int16 nG = (sal_Int16)nParameter - (sal_Int16)aColor.GetGreen(); 3559 sal_Int16 nB = (sal_Int16)nParameter - (sal_Int16)aColor.GetBlue(); 3560 if ( nR < 0 ) 3561 nR = 0; 3562 if ( nG < 0 ) 3563 nG = 0; 3564 if ( nB < 0 ) 3565 nB = 0; 3566 aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB ); 3567 } 3568 break; 3569 case 0x06 : // per component: black if < p, white if >= p 3570 { 3571 aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff ); 3572 aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff ); 3573 aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff ); 3574 } 3575 break; 3576 } 3577 if ( nAdditionalFlags & 0x40 ) // top-bit invert 3578 aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 ); 3579 3580 if ( nAdditionalFlags & 0x20 ) // invert color 3581 aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue()); 3582 } 3583 } 3584 else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) ) 3585 { // case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor 3586 GetColorFromPalette( nUpper, aColor ); 3587 } 3588 else // hart attributiert, eventuell mit Hinweis auf SYSTEMRGB 3589 aColor = Color( (sal_uInt8)nColorCode, (sal_uInt8)( nColorCode >> 8 ), (sal_uInt8)( nColorCode >> 16 ) ); 3590 return aColor; 3591 } 3592 3593 // sj: I just want to set a string for a text object that may contain multiple 3594 // paragraphs. If I now take a look at the follwing code I get the impression that 3595 // our outliner is too complicate to be used properly, 3596 void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const 3597 { 3598 SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj ); 3599 if ( pText ) 3600 { 3601 SdrOutliner& rOutliner = pText->ImpGetDrawOutliner(); 3602 rOutliner.Init( OUTLINERMODE_TEXTOBJECT ); 3603 3604 sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode(); 3605 rOutliner.SetUpdateMode( sal_False ); 3606 rOutliner.SetVertical( pText->IsVerticalWriting() ); 3607 3608 sal_uInt16 nParaIndex = 0; 3609 sal_uInt32 nParaSize; 3610 const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer(); 3611 const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len(); 3612 3613 while( pBuf < pEnd ) 3614 { 3615 pCurrent = pBuf; 3616 3617 for ( nParaSize = 0; pBuf < pEnd; ) 3618 { 3619 sal_Unicode nChar = *pBuf++; 3620 if ( nChar == 0xa ) 3621 { 3622 if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) ) 3623 pBuf++; 3624 break; 3625 } 3626 else if ( nChar == 0xd ) 3627 { 3628 if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) ) 3629 pBuf++; 3630 break; 3631 } 3632 else 3633 nParaSize++; 3634 } 3635 ESelection aSelection( nParaIndex, 0, nParaIndex, 0 ); 3636 String aParagraph( pCurrent, (sal_uInt16)nParaSize ); 3637 if ( !nParaIndex && !aParagraph.Len() ) // SJ: we are crashing if the first paragraph is empty ? 3638 aParagraph += (sal_Unicode)' '; // otherwise these two lines can be removed. 3639 rOutliner.Insert( aParagraph, nParaIndex, 0 ); 3640 rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() ); 3641 3642 SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() ); 3643 if ( !aSelection.nStartPos ) 3644 aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, sal_False ) ); 3645 aSelection.nStartPos = 0; 3646 rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection ); 3647 nParaIndex++; 3648 } 3649 OutlinerParaObject* pNewText = rOutliner.CreateParaObject(); 3650 rOutliner.Clear(); 3651 rOutliner.SetUpdateMode( bOldUpdateMode ); 3652 pText->SetOutlinerParaObject( pNewText ); 3653 } 3654 } 3655 3656 //static 3657 void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr, 3658 sal_uLong nRecLen, FASTBOOL bUniCode ) 3659 { 3660 sal_uInt16 nLen = (sal_uInt16)nRecLen; 3661 if( nLen ) 3662 { 3663 if ( bUniCode ) 3664 nLen >>= 1; 3665 3666 String sBuf; 3667 sal_Unicode* pBuf = sBuf.AllocBuffer( nLen ); 3668 3669 if( bUniCode ) 3670 { 3671 rIn.Read( (sal_Char*)pBuf, nLen << 1 ); 3672 3673 #ifdef OSL_BIGENDIAN 3674 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf ) 3675 *pBuf = SWAPSHORT( *pBuf ); 3676 #endif // ifdef OSL_BIGENDIAN 3677 } 3678 else 3679 { 3680 // use the String-Data as buffer for the 8bit characters and 3681 // change then all to unicode 3682 sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen; 3683 rIn.Read( (sal_Char*)pReadPos, nLen ); 3684 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos ) 3685 *pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 ); 3686 } 3687 3688 rStr = sBuf.EraseTrailingChars( 0 ); 3689 } 3690 else 3691 rStr.Erase(); 3692 } 3693 3694 SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const 3695 { 3696 SdrObject* pRet = NULL; 3697 String aObjectText; 3698 String aFontName; 3699 sal_Bool bTextRotate = sal_False; 3700 3701 ((SvxMSDffManager*)this)->mnFix16Angle = 0; // we don't want to use this property in future 3702 if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) ) 3703 MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True ); 3704 if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) ) 3705 MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True ); 3706 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) 3707 { 3708 // Text ist senkrecht formatiert, Box Kippen 3709 sal_Int32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1; 3710 sal_Int32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1; 3711 Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight, 3712 rBoundRect.Top() + nHalfHeight - nHalfWidth); 3713 Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() ); 3714 Rectangle aNewRect( aTopLeft, aNewSize ); 3715 rBoundRect = aNewRect; 3716 3717 String aSrcText( aObjectText ); 3718 aObjectText.Erase(); 3719 for( sal_uInt16 a = 0; a < aSrcText.Len(); a++ ) 3720 { 3721 aObjectText += aSrcText.GetChar( a ); 3722 aObjectText += '\n'; 3723 } 3724 rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) ); 3725 bTextRotate = sal_True; 3726 } 3727 if ( aObjectText.Len() ) 3728 { // FontWork-Objekt Mit dem Text in aObjectText erzeugen 3729 SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect ); 3730 if( pNewObj ) 3731 { 3732 pNewObj->SetModel( pSdrModel ); 3733 ((SdrRectObj*)pNewObj)->SetText( aObjectText ); 3734 SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL; 3735 rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) ); 3736 rSet.Put( SdrTextAutoGrowHeightItem( sal_False ) ); 3737 rSet.Put( SdrTextAutoGrowWidthItem( sal_False ) ); 3738 rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(), 3739 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO )); 3740 3741 pNewObj->SetMergedItemSet(rSet); 3742 3743 pRet = pNewObj->ConvertToPolyObj( sal_False, sal_False ); 3744 if( !pRet ) 3745 pRet = pNewObj; 3746 else 3747 { 3748 pRet->NbcSetSnapRect( rBoundRect ); 3749 SdrObject::Free( pNewObj ); 3750 } 3751 if( bTextRotate ) 3752 { 3753 double a = 9000 * nPi180; 3754 pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) ); 3755 } 3756 } 3757 } 3758 return pRet; 3759 } 3760 3761 static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted) 3762 { 3763 MapMode aPrefMapMode(rGraf.GetPrefMapMode()); 3764 if (aPrefMapMode == aWanted) 3765 return rGraf.GetPrefSize(); 3766 Size aRetSize; 3767 if (aPrefMapMode == MAP_PIXEL) 3768 { 3769 aRetSize = Application::GetDefaultDevice()->PixelToLogic( 3770 rGraf.GetPrefSize(), aWanted); 3771 } 3772 else 3773 { 3774 aRetSize = Application::GetDefaultDevice()->LogicToLogic( 3775 rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted); 3776 } 3777 return aRetSize; 3778 } 3779 3780 // sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf, 3781 // otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem 3782 static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf ) 3783 { 3784 sal_Int32 nCropTop = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 ); 3785 sal_Int32 nCropBottom = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 ); 3786 sal_Int32 nCropLeft = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 ); 3787 sal_Int32 nCropRight = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 ); 3788 3789 if( nCropTop || nCropBottom || nCropLeft || nCropRight ) 3790 { 3791 double fFactor; 3792 Size aCropSize; 3793 BitmapEx aCropBitmap; 3794 sal_uInt32 nTop( 0 ), nBottom( 0 ), nLeft( 0 ), nRight( 0 ); 3795 3796 if ( pSet ) // use crop attributes ? 3797 aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM ); 3798 else 3799 { 3800 aCropBitmap = rGraf.GetBitmapEx(); 3801 aCropSize = aCropBitmap.GetSizePixel(); 3802 } 3803 if ( nCropTop ) 3804 { 3805 fFactor = (double)nCropTop / 65536.0; 3806 nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 ); 3807 } 3808 if ( nCropBottom ) 3809 { 3810 fFactor = (double)nCropBottom / 65536.0; 3811 nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 ); 3812 } 3813 if ( nCropLeft ) 3814 { 3815 fFactor = (double)nCropLeft / 65536.0; 3816 nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 ); 3817 } 3818 if ( nCropRight ) 3819 { 3820 fFactor = (double)nCropRight / 65536.0; 3821 nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 ); 3822 } 3823 if ( pSet ) // use crop attributes ? 3824 pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) ); 3825 else 3826 { 3827 Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom ); 3828 aCropBitmap.Crop( aCropRect ); 3829 rGraf = aCropBitmap; 3830 } 3831 } 3832 } 3833 3834 SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, const DffObjData& rObjData ) const 3835 { 3836 SdrObject* pRet = NULL; 3837 String aFileName; 3838 String aLinkFileName, aLinkFilterName; 3839 Rectangle aVisArea; 3840 3841 MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault ); 3842 sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 ); 3843 sal_Bool bGrfRead = sal_False, 3844 3845 // Grafik verlinkt 3846 bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile ); 3847 { 3848 Graphic aGraf; // be sure this graphic is deleted before swapping out 3849 if( SeekToContent( DFF_Prop_pibName, rSt ) ) 3850 MSDFFReadZString( rSt, aFileName, GetPropertyValue( DFF_Prop_pibName ), sal_True ); 3851 3852 // UND, ODER folgendes: 3853 if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded 3854 { 3855 bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea ); 3856 if ( !bGrfRead ) 3857 { 3858 /* 3859 Still no luck, lets look at the end of this record for a FBSE pool, 3860 this fallback is a specific case for how word does it sometimes 3861 */ 3862 rObjData.rSpHd.SeekToEndOfRecord( rSt ); 3863 DffRecordHeader aHd; 3864 rSt >> aHd; 3865 if( DFF_msofbtBSE == aHd.nRecType ) 3866 { 3867 const sal_uLong nSkipBLIPLen = 20; 3868 const sal_uLong nSkipShapePos = 4; 3869 const sal_uLong nSkipBLIP = 4; 3870 const sal_uLong nSkip = 3871 nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP; 3872 3873 if (nSkip <= aHd.nRecLen) 3874 { 3875 rSt.SeekRel(nSkip); 3876 if (0 == rSt.GetError()) 3877 bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea ); 3878 } 3879 } 3880 } 3881 } 3882 if ( bGrfRead ) 3883 { 3884 // the writer is doing it's own cropping, so this part affects only impress and calc 3885 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS ) 3886 lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf ); 3887 3888 if ( IsProperty( DFF_Prop_pictureTransparent ) ) 3889 { 3890 sal_uInt32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 ); 3891 3892 if ( aGraf.GetType() == GRAPHIC_BITMAP ) 3893 { 3894 BitmapEx aBitmapEx( aGraf.GetBitmapEx() ); 3895 Bitmap aBitmap( aBitmapEx.GetBitmap() ); 3896 Bitmap aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) ); 3897 if ( aBitmapEx.IsTransparent() ) 3898 aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR ); 3899 aGraf = BitmapEx( aBitmap, aMask ); 3900 } 3901 } 3902 3903 sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 ); 3904 /* 3905 0x10000 is msoffice 50% 3906 < 0x10000 is in units of 1/50th of 0x10000 per 1% 3907 > 0x10000 is in units where 3908 a msoffice x% is stored as 50/(100-x) * 0x10000 3909 3910 plus, a (ui) microsoft % ranges from 0 to 100, OOO 3911 from -100 to 100, so also normalize into that range 3912 */ 3913 if ( nContrast > 0x10000 ) 3914 { 3915 double fX = nContrast; 3916 fX /= 0x10000; 3917 fX /= 51; // 50 + 1 to round 3918 fX = 1/fX; 3919 nContrast = static_cast<sal_Int32>(fX); 3920 nContrast -= 100; 3921 nContrast = -nContrast; 3922 nContrast = (nContrast-50)*2; 3923 } 3924 else if ( nContrast == 0x10000 ) 3925 nContrast = 0; 3926 else 3927 { 3928 nContrast *= 101; //100 + 1 to round 3929 nContrast /= 0x10000; 3930 nContrast -= 100; 3931 } 3932 sal_Int16 nBrightness = (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 ); 3933 sal_Int32 nGamma = GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 ); 3934 GraphicDrawMode eDrawMode = GRAPHICDRAWMODE_STANDARD; 3935 switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 ) 3936 { 3937 case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break; 3938 case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break; 3939 case 0 : 3940 { 3941 //office considers the converted values of (in OOo) 70 to be the 3942 //"watermark" values, which can vary slightly due to rounding from the 3943 //above values 3944 if (( nContrast == -70 ) && ( nBrightness == 70 )) 3945 { 3946 nContrast = 0; 3947 nBrightness = 0; 3948 eDrawMode = GRAPHICDRAWMODE_WATERMARK; 3949 }; 3950 } 3951 break; 3952 } 3953 3954 if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) ) 3955 { 3956 if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ) 3957 { 3958 if ( nBrightness ) 3959 rSet.Put( SdrGrafLuminanceItem( nBrightness ) ); 3960 if ( nContrast ) 3961 rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) ); 3962 if ( nGamma != 0x10000 ) 3963 rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) ); 3964 if ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) 3965 rSet.Put( SdrGrafModeItem( eDrawMode ) ); 3966 } 3967 else 3968 { 3969 if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK ) 3970 { 3971 nContrast = 60; 3972 nBrightness = 70; 3973 eDrawMode = GRAPHICDRAWMODE_STANDARD; 3974 } 3975 switch ( aGraf.GetType() ) 3976 { 3977 case GRAPHIC_BITMAP : 3978 { 3979 BitmapEx aBitmapEx( aGraf.GetBitmapEx() ); 3980 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) ) 3981 aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False ); 3982 if ( eDrawMode == GRAPHICDRAWMODE_GREYS ) 3983 aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS ); 3984 else if ( eDrawMode == GRAPHICDRAWMODE_MONO ) 3985 aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD ); 3986 aGraf = aBitmapEx; 3987 3988 } 3989 break; 3990 3991 case GRAPHIC_GDIMETAFILE : 3992 { 3993 GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() ); 3994 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) ) 3995 aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False ); 3996 if ( eDrawMode == GRAPHICDRAWMODE_GREYS ) 3997 aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS ); 3998 else if ( eDrawMode == GRAPHICDRAWMODE_MONO ) 3999 aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD ); 4000 aGraf = aGdiMetaFile; 4001 } 4002 break; 4003 default: break; 4004 } 4005 } 4006 } 4007 } 4008 4009 // sollte es ein OLE-Object sein? 4010 if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) ) 4011 { 4012 // TODO/LATER: in future probably the correct aspect should be provided here 4013 sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT; 4014 // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method 4015 pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, rObjData.aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect ); 4016 // <-- 4017 } 4018 if( !pRet ) 4019 { 4020 pRet = new SdrGrafObj; 4021 if( bGrfRead ) 4022 ((SdrGrafObj*)pRet)->SetGraphic( aGraf ); 4023 4024 if( bLinkGrf && !bGrfRead ) // sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then 4025 { // we do not need to set a link. TODO: not to lose the information where the graphic is linked from 4026 INetURLObject aAbsURL; 4027 if ( !INetURLObject( maBaseURL ).GetNewAbsURL( ByteString( aFileName, RTL_TEXTENCODING_UTF8 ), &aAbsURL ) ) 4028 { 4029 String aValidURL; 4030 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aFileName, aValidURL ) ) 4031 aAbsURL = INetURLObject( aValidURL ); 4032 } 4033 if( aAbsURL.GetProtocol() != INET_PROT_NOT_VALID ) 4034 { 4035 GraphicFilter* pGrfFilter = GraphicFilter::GetGraphicFilter(); 4036 aLinkFilterName = pGrfFilter->GetImportFormatName( 4037 pGrfFilter->GetImportFormatNumberForShortName( aAbsURL.getExtension() ) ); 4038 aLinkFileName = aAbsURL.GetMainURL( INetURLObject::DECODE_TO_IURI ); 4039 } 4040 else 4041 aLinkFileName = aFileName; 4042 } 4043 } 4044 4045 // set the size from BLIP if there is one 4046 if ( pRet && bGrfRead && !aVisArea.IsEmpty() ) 4047 pRet->SetBLIPSizeRectangle( aVisArea ); 4048 4049 if ( !pRet->GetName().Len() ) // SJ 22.02.00 : PPT OLE IMPORT: 4050 { // name is already set in ImportOLE !! 4051 // JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active 4052 if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment ) 4053 { 4054 INetURLObject aURL; 4055 aURL.SetSmartURL( aFileName ); 4056 pRet->SetName( aURL.getBase() ); 4057 } 4058 else 4059 pRet->SetName( aFileName ); 4060 } 4061 } 4062 pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich 4063 pRet->SetLogicRect( rObjData.aBoundRect ); 4064 4065 if ( pRet->ISA( SdrGrafObj ) ) 4066 { 4067 if( aLinkFileName.Len() ) 4068 ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName ); 4069 4070 if ( bLinkGrf && !bGrfRead ) 4071 { 4072 ((SdrGrafObj*)pRet)->ForceSwapIn(); 4073 Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic()); 4074 lcl_ApplyCropping( *this, &rSet, aGraf ); 4075 } 4076 ((SdrGrafObj*)pRet)->ForceSwapOut(); 4077 } 4078 4079 return pRet; 4080 } 4081 4082 // PptSlidePersistEntry& rPersistEntry, SdPage* pPage 4083 SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData, 4084 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId ) 4085 { 4086 SdrObject* pRet = NULL; 4087 DffRecordHeader aObjHd; 4088 rSt >> aObjHd; 4089 if ( aObjHd.nRecType == DFF_msofbtSpgrContainer ) 4090 { 4091 pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId ); 4092 } 4093 else if ( aObjHd.nRecType == DFF_msofbtSpContainer ) 4094 { 4095 pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId ); 4096 } 4097 aObjHd.SeekToBegOfRecord( rSt ); // FilePos restaurieren 4098 return pRet; 4099 } 4100 4101 SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData, 4102 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, 4103 int nCalledByGroup, sal_Int32* pShapeId ) 4104 { 4105 SdrObject* pRet = NULL; 4106 4107 if( pShapeId ) 4108 *pShapeId = 0; 4109 4110 rHd.SeekToContent( rSt ); 4111 DffRecordHeader aRecHd; // the first atom has to be the SpContainer for the GroupObject 4112 rSt >> aRecHd; 4113 if ( aRecHd.nRecType == DFF_msofbtSpContainer ) 4114 { 4115 sal_Int32 nGroupRotateAngle = 0; 4116 sal_Int32 nSpFlags = 0; 4117 mnFix16Angle = 0; 4118 aRecHd.SeekToBegOfRecord( rSt ); 4119 pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId ); 4120 if ( pRet ) 4121 { 4122 nSpFlags = nGroupShapeFlags; 4123 nGroupRotateAngle = mnFix16Angle; 4124 4125 Rectangle aClientRect( rClientRect ); 4126 4127 Rectangle aGlobalChildRect; 4128 if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() ) 4129 aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect ); 4130 else 4131 aGlobalChildRect = rGlobalChildRect; 4132 4133 if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 ) 4134 || ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) ) 4135 { 4136 sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1; 4137 sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1; 4138 Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight, 4139 aClientRect.Top() + nHalfHeight - nHalfWidth ); 4140 Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() ); 4141 Rectangle aNewRect( aTopLeft, aNewSize ); 4142 aClientRect = aNewRect; 4143 } 4144 4145 // now importing the inner objects of the group 4146 aRecHd.SeekToEndOfRecord( rSt ); 4147 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4148 { 4149 DffRecordHeader aRecHd2; 4150 rSt >> aRecHd2; 4151 if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer ) 4152 { 4153 Rectangle aGroupClientAnchor, aGroupChildAnchor; 4154 GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect ); 4155 aRecHd2.SeekToBegOfRecord( rSt ); 4156 sal_Int32 nShapeId; 4157 SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId ); 4158 if ( pTmp ) 4159 { 4160 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp ); 4161 if( nShapeId ) 4162 insertShapeId( nShapeId, pTmp ); 4163 } 4164 } 4165 else if ( aRecHd2.nRecType == DFF_msofbtSpContainer ) 4166 { 4167 aRecHd2.SeekToBegOfRecord( rSt ); 4168 sal_Int32 nShapeId; 4169 SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId ); 4170 if ( pTmp ) 4171 { 4172 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp ); 4173 if( nShapeId ) 4174 insertShapeId( nShapeId, pTmp ); 4175 } 4176 } 4177 aRecHd2.SeekToEndOfRecord( rSt ); 4178 } 4179 4180 // pRet->NbcSetSnapRect( aGroupBound ); 4181 if ( nGroupRotateAngle ) 4182 { 4183 double a = nGroupRotateAngle * nPi180; 4184 pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) ); 4185 } 4186 if ( nSpFlags & SP_FFLIPV ) // Vertikal gespiegelt? 4187 { // BoundRect in aBoundRect 4188 Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 ); 4189 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4190 pRet->NbcMirror( aLeft, aRight ); 4191 } 4192 if ( nSpFlags & SP_FFLIPH ) // Horizontal gespiegelt? 4193 { // BoundRect in aBoundRect 4194 Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() ); 4195 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4196 pRet->NbcMirror( aTop, aBottom ); 4197 } 4198 } 4199 } 4200 return pRet; 4201 } 4202 4203 SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData, 4204 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, 4205 int nCalledByGroup, sal_Int32* pShapeId ) 4206 { 4207 SdrObject* pRet = NULL; 4208 4209 if( pShapeId ) 4210 *pShapeId = 0; 4211 4212 rHd.SeekToBegOfRecord( rSt ); 4213 DffObjData aObjData( rHd, rClientRect, nCalledByGroup ); 4214 aObjData.bRotateTextWithShape = ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL ) == 0; 4215 maShapeRecords.Consume( rSt, sal_False ); 4216 aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING ); 4217 if ( aObjData.bShapeType ) 4218 { 4219 rSt >> aObjData.nShapeId 4220 >> aObjData.nSpFlags; 4221 aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance; 4222 } 4223 else 4224 { 4225 aObjData.nShapeId = 0; 4226 aObjData.nSpFlags = 0; 4227 aObjData.eShapeType = mso_sptNil; 4228 } 4229 4230 if( pShapeId ) 4231 *pShapeId = aObjData.nShapeId; 4232 4233 if ( mbTracing ) 4234 mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP 4235 ? rtl::OUString::createFromAscii( "GroupShape" ) 4236 : rtl::OUString::createFromAscii( "Shape" ), 4237 rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) ); 4238 aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART ); 4239 if ( aObjData.bOpt ) 4240 { 4241 maShapeRecords.Current()->SeekToBegOfRecord( rSt ); 4242 #ifdef DBG_AUTOSHAPE 4243 ReadPropSet( rSt, pClientData, (sal_uInt32)aObjData.eShapeType ); 4244 #else 4245 ReadPropSet( rSt, pClientData ); 4246 #endif 4247 } 4248 else 4249 { 4250 InitializePropSet( DFF_msofbtOPT ); // get the default PropSet 4251 ( (DffPropertyReader*) this )->mnFix16Angle = 0; 4252 } 4253 aObjData.bOpt2 = maShapeRecords.SeekToContent( rSt, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ); 4254 if ( aObjData.bOpt2 ) 4255 { 4256 maShapeRecords.Current()->SeekToBegOfRecord( rSt ); 4257 pSecPropSet = new DffPropertyReader( *this ); 4258 pSecPropSet->ReadPropSet( rSt, NULL ); 4259 } 4260 4261 aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART ); 4262 if ( aObjData.bChildAnchor ) 4263 { 4264 sal_Int32 l, o, r, u; 4265 rSt >> l >> o >> r >> u; 4266 Scale( l ); 4267 Scale( o ); 4268 Scale( r ); 4269 Scale( u ); 4270 aObjData.aChildAnchor = Rectangle( l, o, r, u ); 4271 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() ) 4272 { 4273 double fl = l; 4274 double fo = o; 4275 double fWidth = r - l; 4276 double fHeight= u - o; 4277 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth(); 4278 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight(); 4279 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left(); 4280 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top(); 4281 fWidth *= fXScale; 4282 fHeight *= fYScale; 4283 aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) ); 4284 } 4285 } 4286 4287 aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART ); 4288 if ( aObjData.bClientAnchor ) 4289 ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData ); 4290 4291 if ( aObjData.bChildAnchor ) 4292 aObjData.aBoundRect = aObjData.aChildAnchor; 4293 4294 if ( aObjData.nSpFlags & SP_FBACKGROUND ) 4295 aObjData.aBoundRect = Rectangle( Point(), Size( 1, 1 ) ); 4296 4297 Rectangle aTextRect; 4298 if ( !aObjData.aBoundRect.IsEmpty() ) 4299 { // Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde 4300 if( mnFix16Angle ) 4301 { 4302 long nAngle = mnFix16Angle; 4303 if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) ) 4304 { 4305 sal_Int32 nHalfWidth = ( aObjData.aBoundRect.GetWidth() + 1 ) >> 1; 4306 sal_Int32 nHalfHeight = ( aObjData.aBoundRect.GetHeight() + 1 ) >> 1; 4307 Point aTopLeft( aObjData.aBoundRect.Left() + nHalfWidth - nHalfHeight, 4308 aObjData.aBoundRect.Top() + nHalfHeight - nHalfWidth ); 4309 Size aNewSize( aObjData.aBoundRect.GetHeight(), aObjData.aBoundRect.GetWidth() ); 4310 Rectangle aNewRect( aTopLeft, aNewSize ); 4311 aObjData.aBoundRect = aNewRect; 4312 } 4313 } 4314 aTextRect = aObjData.aBoundRect; 4315 FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) || 4316 IsProperty( DFF_Prop_pibName ) || 4317 IsProperty( DFF_Prop_pibFlags ); 4318 4319 if ( aObjData.nSpFlags & SP_FGROUP ) 4320 { 4321 pRet = new SdrObjGroup; 4322 /* After CWS aw033 has been integrated, an empty group object 4323 cannot store its resulting bounding rectangle anymore. We have 4324 to return this rectangle via rClientRect now, but only, if 4325 caller has not passed an own bounding ractangle. */ 4326 if ( rClientRect.IsEmpty() ) 4327 rClientRect = aObjData.aBoundRect; 4328 nGroupShapeFlags = aObjData.nSpFlags; // #73013# 4329 } 4330 else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic ) 4331 { 4332 SfxItemSet aSet( pSdrModel->GetItemPool() ); 4333 4334 sal_Bool bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) ); 4335 sal_Bool bIsCustomShape = sal_False; 4336 sal_Int32 nObjectRotation = mnFix16Angle; 4337 sal_uInt32 nSpFlags = aObjData.nSpFlags; 4338 4339 if ( bGraphic ) 4340 { 4341 pRet = ImportGraphic( rSt, aSet, aObjData ); // SJ: #68396# is no longer true (fixed in ppt2000) 4342 ApplyAttributes( rSt, aSet, aObjData ); 4343 pRet->SetMergedItemSet(aSet); 4344 } 4345 else if ( aObjData.eShapeType == mso_sptLine ) 4346 { 4347 basegfx::B2DPolygon aPoly; 4348 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Left(), aObjData.aBoundRect.Top())); 4349 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Right(), aObjData.aBoundRect.Bottom())); 4350 pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly)); 4351 pRet->SetModel( pSdrModel ); 4352 ApplyAttributes( rSt, aSet, aObjData ); 4353 pRet->SetMergedItemSet(aSet); 4354 } 4355 else 4356 { 4357 if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) ) 4358 { 4359 4360 ApplyAttributes( rSt, aSet, aObjData ); 4361 4362 // the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute 4363 // aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) ); 4364 pRet = new SdrObjCustomShape(); 4365 pRet->SetModel( pSdrModel ); 4366 4367 sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0; 4368 4369 // in case of a FontWork, the text is set by the escher import 4370 if ( bIsFontwork ) 4371 { 4372 String aObjectText; 4373 String aFontName; 4374 MSO_GeoTextAlign eGeoTextAlign; 4375 4376 if ( SeekToContent( DFF_Prop_gtextFont, rSt ) ) 4377 { 4378 SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL); 4379 GetDefaultFonts( aLatin, aAsian, aComplex ); 4380 4381 MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True ); 4382 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(), 4383 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO )); 4384 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(), 4385 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) ); 4386 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(), 4387 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) ); 4388 } 4389 4390 // SJ: applying fontattributes for Fontwork : 4391 if ( IsHardAttribute( DFF_Prop_gtextFItalic ) ) 4392 aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) ); 4393 4394 if ( IsHardAttribute( DFF_Prop_gtextFBold ) ) 4395 aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); 4396 4397 // SJ TODO: Vertical Writing is not correct, instead this should be 4398 // replaced through "CharacterRotation" by 90�, therefore a new Item has to be 4399 // supported by svx core, api and xml file format 4400 ((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 ); 4401 4402 if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) ) 4403 { 4404 MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True ); 4405 ReadObjText( aObjectText, pRet ); 4406 } 4407 4408 eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) ); 4409 { 4410 SdrTextHorzAdjust eHorzAdjust; 4411 switch( eGeoTextAlign ) 4412 { 4413 case mso_alignTextLetterJust : 4414 case mso_alignTextWordJust : 4415 case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break; 4416 default: 4417 case mso_alignTextInvalid : 4418 case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break; 4419 case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break; 4420 case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break; 4421 } 4422 aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) ); 4423 4424 SdrFitToSizeType eFTS = SDRTEXTFIT_NONE; 4425 if ( eGeoTextAlign == mso_alignTextStretch ) 4426 eFTS = SDRTEXTFIT_ALLLINES; 4427 aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) ); 4428 } 4429 if ( IsProperty( DFF_Prop_gtextSpacing ) ) 4430 { 4431 sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655; 4432 if ( nTextWidth != 100 ) 4433 aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) ); 4434 } 4435 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 ) // SJ: Font Kerning On ? 4436 aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) ); 4437 } 4438 pRet->SetMergedItemSet( aSet ); 4439 4440 // sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set 4441 // proper text directions, instead the text default is depending to the string. 4442 // so we have to calculate the a text direction from string: 4443 if ( bIsFontwork ) 4444 { 4445 OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject(); 4446 if ( pParaObj ) 4447 { 4448 SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner(); 4449 sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode(); 4450 SdrModel* pModel = pRet->GetModel(); 4451 if ( pModel ) 4452 rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() ); 4453 rOutliner.SetUpdateMode( sal_False ); 4454 rOutliner.SetText( *pParaObj ); 4455 VirtualDevice aVirDev( 1 ); 4456 aVirDev.SetMapMode( MAP_100TH_MM ); 4457 sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount(); 4458 if ( nParagraphs ) 4459 { 4460 sal_Bool bCreateNewParaObject = sal_False; 4461 for ( i = 0; i < nParagraphs; i++ ) 4462 { 4463 sal_Bool bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN ); 4464 if ( bIsRTL ) 4465 { 4466 SfxItemSet aSet2( rOutliner.GetParaAttribs( (sal_uInt16)i ) ); 4467 aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) ); 4468 rOutliner.SetParaAttribs( (sal_uInt16)i, aSet2 ); 4469 bCreateNewParaObject = sal_True; 4470 } 4471 } 4472 if ( bCreateNewParaObject ) 4473 { 4474 OutlinerParaObject* pNewText = rOutliner.CreateParaObject(); 4475 rOutliner.Init( OUTLINERMODE_TEXTOBJECT ); 4476 ((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText ); 4477 } 4478 } 4479 rOutliner.Clear(); 4480 rOutliner.SetUpdateMode( bOldUpdateMode ); 4481 } 4482 } 4483 4484 // mso_sptArc special treating: 4485 // sj: since we actually can't render the arc because of its weird SnapRect settings, 4486 // we will create a new CustomShape, that can be saved/loaded without problems. 4487 // We will change the shape type, so this code applys only if importing arcs from msoffice. 4488 if ( aObjData.eShapeType == mso_sptArc ) 4489 { 4490 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) ); 4491 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) ); 4492 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) ); 4493 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) ); 4494 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) ); 4495 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) ); 4496 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) ); 4497 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); 4498 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates; 4499 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues; 4500 4501 // before clearing the GeometryItem we have to store the current Coordinates 4502 const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates ); 4503 Rectangle aPolyBoundRect; 4504 Point aStartPt( 0,0 ); 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 if ( nNumElemVert >= 3 ) 4522 { // arc first command is always wr -- clockwise arc 4523 // the parameters are : (left,top),(right,bottom),start(x,y),end(x,y) 4524 aStartPt = aXP[2]; 4525 } 4526 } 4527 else 4528 aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 ); // defaulting 4529 4530 // clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry 4531 aGeometryItem.ClearPropertyValue( sHandles ); 4532 aGeometryItem.ClearPropertyValue( sEquations ); 4533 aGeometryItem.ClearPropertyValue( sViewBox ); 4534 aGeometryItem.ClearPropertyValue( sPath ); 4535 4536 sal_Int32 nEndAngle = 9000; 4537 sal_Int32 nStartAngle = 0; 4538 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues ); 4539 if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 ) 4540 { 4541 double fNumber; 4542 if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE ) 4543 { 4544 seqAdjustmentValues[ 0 ].Value >>= fNumber; 4545 nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 ); 4546 } 4547 else 4548 { 4549 fNumber = 270.0; 4550 //normal situation:if endAngle != 90,there will be a direct_value,but for damaged curve,the endAngle need to recalculate. 4551 Point cent = aPolyBoundRect.Center(); 4552 if ( aStartPt.Y() == cent.Y() ) 4553 fNumber = ( aStartPt.X() >= cent.X() ) ? 0:180.0; 4554 else if ( aStartPt.X() == cent.X() ) 4555 fNumber = ( aStartPt.Y() >= cent.Y() ) ? 90.0: 270.0; 4556 else 4557 { 4558 fNumber = atan2( double( aStartPt.X() - cent.X() ),double( aStartPt.Y() - cent.Y() ) )+ F_PI; // 0..2PI 4559 fNumber /= F_PI180; // 0..360.0 4560 } 4561 nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 ); 4562 seqAdjustmentValues[ 0 ].Value <<= fNumber; 4563 seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // so this value will properly be stored 4564 } 4565 4566 if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE ) 4567 { 4568 seqAdjustmentValues[ 1 ].Value >>= fNumber; 4569 nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 ); 4570 } 4571 else 4572 { 4573 fNumber = 0.0; 4574 seqAdjustmentValues[ 1 ].Value <<= fNumber; 4575 seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; 4576 } 4577 4578 PropertyValue aPropVal; 4579 aPropVal.Name = sAdjustmentValues; 4580 aPropVal.Value <<= seqAdjustmentValues; 4581 aGeometryItem.SetPropertyValue( aPropVal ); // storing the angle attribute 4582 } 4583 if ( nStartAngle != nEndAngle ) 4584 { 4585 XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2, 4586 (sal_uInt16)nStartAngle / 10, (sal_uInt16)nEndAngle / 10, sal_True ); 4587 Rectangle aPolyPieRect( aXPoly.GetBoundRect() ); 4588 4589 double fYScale, fXScale; 4590 double fYOfs, fXOfs; 4591 4592 Point aP( aObjData.aBoundRect.Center() ); 4593 Size aS( aObjData.aBoundRect.GetSize() ); 4594 aP.X() -= aS.Width() / 2; 4595 aP.Y() -= aS.Height() / 2; 4596 Rectangle aLogicRect( aP, aS ); 4597 4598 fYOfs = fXOfs = 0.0; 4599 4600 if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() ) 4601 { 4602 fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth(); 4603 if ( nSpFlags & SP_FFLIPH ) 4604 fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale; 4605 else 4606 fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale; 4607 } 4608 if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() ) 4609 { 4610 fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight(); 4611 if ( nSpFlags & SP_FFLIPV ) 4612 fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale; 4613 else 4614 fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale; 4615 } 4616 4617 fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth(); 4618 fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight(); 4619 4620 Rectangle aOldBoundRect( aObjData.aBoundRect ); 4621 aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ), 4622 Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) ); 4623 4624 // creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system 4625 double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth(); 4626 double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight(); 4627 sal_Int32 nLeft = (sal_Int32)(( aPolyPieRect.Left() - aPolyBoundRect.Left() ) * fTextFrameScaleX ); 4628 sal_Int32 nTop = (sal_Int32)(( aPolyPieRect.Top() - aPolyBoundRect.Top() ) * fTextFrameScaleY ); 4629 sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX ); 4630 sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() ) * fTextFrameScaleY ); 4631 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 ); 4632 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First, nLeft ); 4633 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second, nTop ); 4634 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight ); 4635 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom ); 4636 PropertyValue aProp; 4637 aProp.Name = sTextFrames; 4638 aProp.Value <<= aTextFrame; 4639 aGeometryItem.SetPropertyValue( sPath, aProp ); 4640 4641 // sj: taking care of the different rotation points, since the new arc is having a bigger snaprect 4642 if ( mnFix16Angle ) 4643 { 4644 sal_Int32 nAngle = mnFix16Angle; 4645 if ( nSpFlags & SP_FFLIPH ) 4646 nAngle = 36000 - nAngle; 4647 if ( nSpFlags & SP_FFLIPV ) 4648 nAngle = -nAngle; 4649 double a = nAngle * F_PI18000; 4650 double ss = sin( a ); 4651 double cc = cos( a ); 4652 Point aP1( aOldBoundRect.TopLeft() ); 4653 Point aC1( aObjData.aBoundRect.Center() ); 4654 Point aP2( aOldBoundRect.TopLeft() ); 4655 Point aC2( aOldBoundRect.Center() ); 4656 RotatePoint( aP1, aC1, ss, cc ); 4657 RotatePoint( aP2, aC2, ss, cc ); 4658 aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() ); 4659 } 4660 } 4661 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem ); 4662 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes(); 4663 4664 // now setting a new name, so the above correction is only done once when importing from ms 4665 SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); 4666 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 4667 const rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) ); 4668 PropertyValue aPropVal; 4669 aPropVal.Name = sType; 4670 aPropVal.Value <<= sName; 4671 aGeoName.SetPropertyValue( aPropVal ); 4672 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName ); 4673 } 4674 else 4675 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes(); 4676 4677 pRet->SetSnapRect( aObjData.aBoundRect ); 4678 EnhancedCustomShape2d aCustomShape2d( pRet ); 4679 aTextRect = aCustomShape2d.GetTextRect(); 4680 4681 bIsCustomShape = sal_True; 4682 4683 if( bIsConnector ) 4684 { 4685 if( nObjectRotation ) 4686 { 4687 double a = nObjectRotation * nPi180; 4688 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) ); 4689 } 4690 // Horizontal gespiegelt? 4691 if ( nSpFlags & SP_FFLIPH ) 4692 { 4693 Rectangle aBndRect( pRet->GetSnapRect() ); 4694 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() ); 4695 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4696 pRet->NbcMirror( aTop, aBottom ); 4697 } 4698 // Vertikal gespiegelt? 4699 if ( nSpFlags & SP_FFLIPV ) 4700 { 4701 Rectangle aBndRect( pRet->GetSnapRect() ); 4702 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 ); 4703 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4704 pRet->NbcMirror( aLeft, aRight ); 4705 } 4706 basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) ); 4707 SdrObject::Free( pRet ); 4708 4709 pRet = new SdrEdgeObj(); 4710 ApplyAttributes( rSt, aSet, aObjData ); 4711 pRet->SetLogicRect( aObjData.aBoundRect ); 4712 pRet->SetMergedItemSet(aSet); 4713 4714 // Konnektoren 4715 MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight ); 4716 4717 ((SdrEdgeObj*)pRet)->ConnectToNode(sal_True, NULL); 4718 ((SdrEdgeObj*)pRet)->ConnectToNode(sal_False, NULL); 4719 4720 Point aPoint1( aObjData.aBoundRect.TopLeft() ); 4721 Point aPoint2( aObjData.aBoundRect.BottomRight() ); 4722 4723 // Rotationen beachten 4724 if ( nObjectRotation ) 4725 { 4726 double a = nObjectRotation * nPi180; 4727 Point aCenter( aObjData.aBoundRect.Center() ); 4728 double ss = sin(a); 4729 double cc = cos(a); 4730 4731 RotatePoint(aPoint1, aCenter, ss, cc); 4732 RotatePoint(aPoint2, aCenter, ss, cc); 4733 } 4734 4735 // Linie innerhalb des Bereiches zurechtdrehen/spiegeln 4736 if ( nSpFlags & SP_FFLIPH ) 4737 { 4738 sal_Int32 n = aPoint1.X(); 4739 aPoint1.X() = aPoint2.X(); 4740 aPoint2.X() = n; 4741 } 4742 if ( nSpFlags & SP_FFLIPV ) 4743 { 4744 sal_Int32 n = aPoint1.Y(); 4745 aPoint1.Y() = aPoint2.Y(); 4746 aPoint2.Y() = n; 4747 } 4748 nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH ); 4749 4750 pRet->NbcSetPoint(aPoint1, 0L); // Startpunkt 4751 pRet->NbcSetPoint(aPoint2, 1L); // Endpunkt 4752 4753 sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist; 4754 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0; 4755 switch( eConnectorStyle ) 4756 { 4757 case mso_cxstyleBent: 4758 { 4759 aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) ); 4760 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630; 4761 } 4762 break; 4763 case mso_cxstyleCurved: 4764 aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) ); 4765 break; 4766 default: // mso_cxstyleStraight || mso_cxstyleNone 4767 aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) ); 4768 break; 4769 } 4770 aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) ); 4771 aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) ); 4772 aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) ); 4773 aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) ); 4774 4775 ((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly ); 4776 pRet->SetMergedItemSet( aSet ); 4777 } 4778 } 4779 } 4780 4781 if ( pRet ) 4782 { 4783 if( nObjectRotation ) 4784 { 4785 double a = nObjectRotation * nPi180; 4786 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) ); 4787 } 4788 // Horizontal gespiegelt? 4789 if ( nSpFlags & SP_FFLIPH ) 4790 { 4791 Rectangle aBndRect( pRet->GetSnapRect() ); 4792 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() ); 4793 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4794 pRet->NbcMirror( aTop, aBottom ); 4795 } 4796 // Vertikal gespiegelt? 4797 if ( nSpFlags & SP_FFLIPV ) 4798 { 4799 Rectangle aBndRect( pRet->GetSnapRect() ); 4800 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 ); 4801 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4802 pRet->NbcMirror( aLeft, aRight ); 4803 } 4804 } 4805 } 4806 } 4807 4808 // #i51348# #118052# name of the shape 4809 if( pRet ) 4810 { 4811 ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt ); 4812 if( aObjName.getLength() > 0 ) 4813 pRet->SetName( aObjName ); 4814 } 4815 4816 pRet = 4817 ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet); 4818 4819 if ( pRet ) 4820 { 4821 sal_Int32 nGroupProperties( GetPropertyValue( DFF_Prop_fPrint ) ); 4822 pRet->SetVisible( ( nGroupProperties & 2 ) == 0 ); 4823 pRet->SetPrintable( ( nGroupProperties & 1 ) != 0 ); 4824 } 4825 4826 if ( mbTracing ) 4827 mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP 4828 ? rtl::OUString::createFromAscii( "GroupShape" ) 4829 : rtl::OUString::createFromAscii( "Shape" ) ); 4830 //Import alt text as description 4831 if ( pRet && SeekToContent( DFF_Prop_wzDescription, rSt ) ) 4832 { 4833 String aAltText; 4834 MSDFFReadZString( rSt, aAltText, GetPropertyValue( DFF_Prop_wzDescription ), sal_True ); 4835 pRet->SetDescription( aAltText ); 4836 } 4837 4838 return pRet; 4839 } 4840 4841 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect ) 4842 { 4843 Rectangle aChildAnchor; 4844 rHd.SeekToContent( rSt ); 4845 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4846 { 4847 DffRecordHeader aShapeHd; 4848 rSt >> aShapeHd; 4849 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || 4850 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) 4851 { 4852 DffRecordHeader aShapeHd2( aShapeHd ); 4853 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) 4854 rSt >> aShapeHd2; 4855 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) ) 4856 { 4857 DffRecordHeader aShapeAtom; 4858 rSt >> aShapeAtom; 4859 4860 if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor ) 4861 { 4862 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT ) 4863 { 4864 sal_Int32 l, t, r, b; 4865 if ( aShapeAtom.nRecLen == 16 ) 4866 { 4867 rSt >> l >> t >> r >> b; 4868 } 4869 else 4870 { 4871 sal_Int16 ls, ts, rs, bs; 4872 rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ... 4873 l = ls, t = ts, r = rs, b = bs; 4874 } 4875 Scale( l ); 4876 Scale( t ); 4877 Scale( r ); 4878 Scale( b ); 4879 aClientRect = Rectangle( l, t, r, b ); 4880 } 4881 break; 4882 } 4883 else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor ) 4884 { 4885 sal_Int32 l, o, r, u; 4886 rSt >> l >> o >> r >> u; 4887 Scale( l ); 4888 Scale( o ); 4889 Scale( r ); 4890 Scale( u ); 4891 Rectangle aChild( l, o, r, u ); 4892 aChildAnchor.Union( aChild ); 4893 break; 4894 } 4895 aShapeAtom.SeekToEndOfRecord( rSt ); 4896 } 4897 } 4898 aShapeHd.SeekToEndOfRecord( rSt ); 4899 } 4900 return aChildAnchor; 4901 } 4902 4903 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt, 4904 Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor, 4905 const Rectangle& rClientRect, const Rectangle& rGlobalChildRect ) 4906 { 4907 sal_Bool bFirst = sal_True; 4908 rHd.SeekToContent( rSt ); 4909 DffRecordHeader aShapeHd; 4910 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4911 { 4912 rSt >> aShapeHd; 4913 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || 4914 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) 4915 { 4916 DffRecordHeader aShapeHd2( aShapeHd ); 4917 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) 4918 rSt >> aShapeHd2; 4919 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) ) 4920 { 4921 DffRecordHeader aShapeAtom; 4922 rSt >> aShapeAtom; 4923 if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor ) 4924 { 4925 sal_Int32 l, o, r, u; 4926 rSt >> l >> o >> r >> u; 4927 Scale( l ); 4928 Scale( o ); 4929 Scale( r ); 4930 Scale( u ); 4931 Rectangle aChild( l, o, r, u ); 4932 4933 if ( bFirst ) 4934 { 4935 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() ) 4936 { 4937 double fl = l; 4938 double fo = o; 4939 double fWidth = r - l; 4940 double fHeight= u - o; 4941 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth(); 4942 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight(); 4943 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left(); 4944 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top(); 4945 fWidth *= fXScale; 4946 fHeight *= fYScale; 4947 rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) ); 4948 } 4949 bFirst = sal_False; 4950 } 4951 else 4952 rGroupChildAnchor.Union( aChild ); 4953 break; 4954 } 4955 aShapeAtom.SeekToEndOfRecord( rSt ); 4956 } 4957 } 4958 aShapeHd.SeekToEndOfRecord( rSt ); 4959 } 4960 } 4961 4962 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt, 4963 DffObjData& rObjData, 4964 void* pData, 4965 Rectangle& rTextRect, 4966 SdrObject* pObj 4967 ) 4968 { 4969 if( !rTextRect.IsEmpty() ) 4970 { 4971 SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData; 4972 SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec; 4973 SvxMSDffImportRec* pTextImpRec = pImpRec; 4974 4975 // fill Import Record with data 4976 pImpRec->nShapeId = rObjData.nShapeId; 4977 pImpRec->eShapeType = rObjData.eShapeType; 4978 4979 MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue( 4980 DFF_Prop_WrapText, 4981 mso_wrapSquare ) ); 4982 rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, 4983 DFF_msofbtClientAnchor, 4984 SEEK_FROM_CURRENT_AND_RESTART ); 4985 if( rObjData.bClientAnchor ) 4986 ProcessClientAnchor( rSt, 4987 maShapeRecords.Current()->nRecLen, 4988 pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen ); 4989 4990 rObjData.bClientData = maShapeRecords.SeekToContent( rSt, 4991 DFF_msofbtClientData, 4992 SEEK_FROM_CURRENT_AND_RESTART ); 4993 if( rObjData.bClientData ) 4994 ProcessClientData( rSt, 4995 maShapeRecords.Current()->nRecLen, 4996 pImpRec->pClientDataBuffer, pImpRec->nClientDataLen ); 4997 4998 4999 // process user (== Winword) defined parameters in 0xF122 record 5000 if( maShapeRecords.SeekToContent( rSt, 5001 DFF_msofbtUDefProp, 5002 SEEK_FROM_CURRENT_AND_RESTART ) 5003 && maShapeRecords.Current()->nRecLen ) 5004 { 5005 sal_uInt32 nBytesLeft = maShapeRecords.Current()->nRecLen; 5006 sal_uInt32 nUDData; 5007 sal_uInt16 nPID; 5008 while( 5 < nBytesLeft ) 5009 { 5010 rSt >> nPID; 5011 if ( rSt.GetError() != 0 ) 5012 break; 5013 rSt >> nUDData; 5014 switch( nPID ) 5015 { 5016 case 0x038F: pImpRec->nXAlign = nUDData; break; 5017 case 0x0390: pImpRec->nXRelTo = nUDData; break; 5018 case 0x0391: pImpRec->nYAlign = nUDData; break; 5019 case 0x0392: pImpRec->nYRelTo = nUDData; break; 5020 case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break; 5021 } 5022 if ( rSt.GetError() != 0 ) 5023 break; 5024 pImpRec->bHasUDefProp = sal_True; 5025 nBytesLeft -= 6; 5026 } 5027 } 5028 5029 // Textrahmen, auch Title oder Outline 5030 SdrObject* pOrgObj = pObj; 5031 SdrRectObj* pTextObj = 0; 5032 sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 ); 5033 if( nTextId ) 5034 { 5035 SfxItemSet aSet( pSdrModel->GetItemPool() ); 5036 5037 //Originally anything that as a mso_sptTextBox was created as a 5038 //textbox, this was changed for #88277# to be created as a simple 5039 //rect to keep impress happy. For the rest of us we'd like to turn 5040 //it back into a textbox again. 5041 FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox); 5042 if (!bTextFrame) 5043 { 5044 //Either 5045 //a) its a simple text object or 5046 //b) its a rectangle with text and square wrapping. 5047 bTextFrame = 5048 ( 5049 (pImpRec->eShapeType == mso_sptTextSimple) || 5050 ( 5051 (pImpRec->eShapeType == mso_sptRectangle) 5052 && (eWrapMode == mso_wrapSquare) 5053 && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() ) 5054 ) 5055 ); 5056 } 5057 5058 if (bTextFrame) 5059 { 5060 SdrObject::Free( pObj ); 5061 pObj = pOrgObj = 0; 5062 } 5063 5064 // Distance of Textbox to it's surrounding Customshape 5065 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L); 5066 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L ); 5067 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L ); 5068 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L ); 5069 5070 ScaleEmu( nTextLeft ); 5071 ScaleEmu( nTextRight ); 5072 ScaleEmu( nTextTop ); 5073 ScaleEmu( nTextBottom ); 5074 5075 sal_Int32 nTextRotationAngle=0; 5076 bool bVerticalText = false; 5077 if ( IsProperty( DFF_Prop_txflTextFlow ) ) 5078 { 5079 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue( 5080 DFF_Prop_txflTextFlow) & 0xFFFF); 5081 switch( eTextFlow ) 5082 { 5083 case mso_txflBtoT: 5084 nTextRotationAngle = 9000; 5085 break; 5086 case mso_txflVertN: 5087 case mso_txflTtoBN: 5088 nTextRotationAngle = 27000; 5089 break; 5090 case mso_txflTtoBA: 5091 bVerticalText = true; 5092 break; 5093 case mso_txflHorzA: 5094 bVerticalText = true; 5095 nTextRotationAngle = 9000; 5096 case mso_txflHorzN: 5097 default : 5098 break; 5099 } 5100 } 5101 5102 if (nTextRotationAngle) 5103 { 5104 while (nTextRotationAngle > 360000) 5105 nTextRotationAngle-=9000; 5106 switch (nTextRotationAngle) 5107 { 5108 case 9000: 5109 { 5110 long nWidth = rTextRect.GetWidth(); 5111 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight(); 5112 rTextRect.Bottom() = rTextRect.Top() + nWidth; 5113 5114 sal_Int32 nOldTextLeft = nTextLeft; 5115 sal_Int32 nOldTextRight = nTextRight; 5116 sal_Int32 nOldTextTop = nTextTop; 5117 sal_Int32 nOldTextBottom = nTextBottom; 5118 5119 nTextLeft = nOldTextBottom; 5120 nTextRight = nOldTextTop; 5121 nTextTop = nOldTextLeft; 5122 nTextBottom = nOldTextRight; 5123 } 5124 break; 5125 case 27000: 5126 { 5127 long nWidth = rTextRect.GetWidth(); 5128 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight(); 5129 rTextRect.Bottom() = rTextRect.Top() + nWidth; 5130 5131 sal_Int32 nOldTextLeft = nTextLeft; 5132 sal_Int32 nOldTextRight = nTextRight; 5133 sal_Int32 nOldTextTop = nTextTop; 5134 sal_Int32 nOldTextBottom = nTextBottom; 5135 5136 nTextLeft = nOldTextTop; 5137 nTextRight = nOldTextBottom; 5138 nTextTop = nOldTextRight; 5139 nTextBottom = nOldTextLeft; 5140 } 5141 break; 5142 default: 5143 break; 5144 } 5145 } 5146 5147 pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect); 5148 pTextImpRec = new SvxMSDffImportRec(*pImpRec); 5149 5150 // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin, 5151 // hier rausrechnen 5152 Rectangle aNewRect(rTextRect); 5153 aNewRect.Bottom() -= nTextTop + nTextBottom; 5154 aNewRect.Right() -= nTextLeft + nTextRight; 5155 5156 // Nur falls es eine einfache Textbox ist, darf der Writer 5157 // das Objekt durch einen Rahmen ersetzen, ansonsten 5158 if( bTextFrame ) 5159 { 5160 SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId ); 5161 aTmpRec.bSortByShapeId = sal_True; 5162 5163 sal_uInt16 nFound; 5164 if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) ) 5165 { 5166 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound); 5167 pTextImpRec->bReplaceByFly = rInfo.bReplaceByFly; 5168 pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain; 5169 } 5170 } 5171 5172 if( !pObj ) 5173 ApplyAttributes( rSt, aSet, rObjData ); 5174 5175 bool bFitText = false; 5176 if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2) 5177 { 5178 aSet.Put( SdrTextAutoGrowHeightItem( sal_True ) ); 5179 aSet.Put( SdrTextMinFrameHeightItem( 5180 aNewRect.Bottom() - aNewRect.Top() ) ); 5181 aSet.Put( SdrTextMinFrameWidthItem( 5182 aNewRect.Right() - aNewRect.Left() ) ); 5183 bFitText = true; 5184 } 5185 else 5186 { 5187 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) ); 5188 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) ); 5189 } 5190 5191 switch ( (MSO_WrapMode) 5192 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) ) 5193 { 5194 case mso_wrapNone : 5195 aSet.Put( SdrTextAutoGrowWidthItem( sal_True ) ); 5196 if (bFitText) 5197 { 5198 //can't do autowidth in flys #i107184# 5199 pTextImpRec->bReplaceByFly = false; 5200 } 5201 break; 5202 case mso_wrapByPoints : 5203 aSet.Put( SdrTextContourFrameItem( sal_True ) ); 5204 break; 5205 default: break; 5206 } 5207 5208 // Abstaende an den Raendern der Textbox setzen 5209 aSet.Put( SdrTextLeftDistItem( nTextLeft ) ); 5210 aSet.Put( SdrTextRightDistItem( nTextRight ) ); 5211 aSet.Put( SdrTextUpperDistItem( nTextTop ) ); 5212 aSet.Put( SdrTextLowerDistItem( nTextBottom ) ); 5213 pTextImpRec->nDxTextLeft = nTextLeft; 5214 pTextImpRec->nDyTextTop = nTextTop; 5215 pTextImpRec->nDxTextRight = nTextRight; 5216 pTextImpRec->nDyTextBottom = nTextBottom; 5217 5218 // Textverankerung lesen 5219 if ( IsProperty( DFF_Prop_anchorText ) ) 5220 { 5221 MSO_Anchor eTextAnchor = 5222 (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText ); 5223 5224 SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER; 5225 sal_Bool bTVASet(sal_False); 5226 SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER; 5227 sal_Bool bTHASet(sal_False); 5228 5229 switch( eTextAnchor ) 5230 { 5231 case mso_anchorTop: 5232 { 5233 eTVA = SDRTEXTVERTADJUST_TOP; 5234 bTVASet = sal_True; 5235 } 5236 break; 5237 case mso_anchorTopCentered: 5238 { 5239 eTVA = SDRTEXTVERTADJUST_TOP; 5240 bTVASet = sal_True; 5241 bTHASet = sal_True; 5242 } 5243 break; 5244 5245 case mso_anchorMiddle: 5246 bTVASet = sal_True; 5247 break; 5248 case mso_anchorMiddleCentered: 5249 { 5250 bTVASet = sal_True; 5251 bTHASet = sal_True; 5252 } 5253 break; 5254 case mso_anchorBottom: 5255 { 5256 eTVA = SDRTEXTVERTADJUST_BOTTOM; 5257 bTVASet = sal_True; 5258 } 5259 break; 5260 case mso_anchorBottomCentered: 5261 { 5262 eTVA = SDRTEXTVERTADJUST_BOTTOM; 5263 bTVASet = sal_True; 5264 bTHASet = sal_True; 5265 } 5266 break; 5267 /* 5268 case mso_anchorTopBaseline: 5269 case mso_anchorBottomBaseline: 5270 case mso_anchorTopCenteredBaseline: 5271 case mso_anchorBottomCenteredBaseline: 5272 break; 5273 */ 5274 default : break; 5275 } 5276 // Einsetzen 5277 if ( bTVASet ) 5278 aSet.Put( SdrTextVertAdjustItem( eTVA ) ); 5279 if ( bTHASet ) 5280 aSet.Put( SdrTextHorzAdjustItem( eTHA ) ); 5281 } 5282 5283 pTextObj->SetMergedItemSet(aSet); 5284 pTextObj->SetModel(pSdrModel); 5285 5286 if (bVerticalText) 5287 pTextObj->SetVerticalWriting(sal_True); 5288 5289 if (nTextRotationAngle) 5290 { 5291 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ? 5292 rTextRect.GetWidth() : rTextRect.GetHeight(); 5293 nMinWH /= 2; 5294 Point aPivot(rTextRect.TopLeft()); 5295 aPivot.X() += nMinWH; 5296 aPivot.Y() += nMinWH; 5297 double a = nTextRotationAngle * nPi180; 5298 pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a)); 5299 } 5300 5301 // rotate text with shape ? 5302 if ( mnFix16Angle ) 5303 { 5304 double a = mnFix16Angle * nPi180; 5305 pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle, 5306 sin( a ), cos( a ) ); 5307 } 5308 5309 if( !pObj ) 5310 { 5311 pObj = pTextObj; 5312 } 5313 else 5314 { 5315 if( pTextObj != pObj ) 5316 { 5317 SdrObject* pGroup = new SdrObjGroup; 5318 pGroup->GetSubList()->NbcInsertObject( pObj ); 5319 pGroup->GetSubList()->NbcInsertObject( pTextObj ); 5320 if (pOrgObj == pObj) 5321 pOrgObj = pGroup; 5322 else 5323 pOrgObj = pObj; 5324 pObj = pGroup; 5325 } 5326 } 5327 } 5328 else if( !pObj ) 5329 { 5330 // simple rectangular objects are ignored by ImportObj() :-( 5331 // this is OK for Draw but not for Calc and Writer 5332 // cause here these objects have a default border 5333 pObj = new SdrRectObj(rTextRect); 5334 pOrgObj = pObj; 5335 pObj->SetModel( pSdrModel ); 5336 SfxItemSet aSet( pSdrModel->GetItemPool() ); 5337 ApplyAttributes( rSt, aSet, rObjData ); 5338 5339 const SfxPoolItem* pPoolItem=NULL; 5340 SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR, 5341 sal_False, &pPoolItem ); 5342 if( SFX_ITEM_DEFAULT == eState ) 5343 aSet.Put( XFillColorItem( String(), 5344 Color( mnDefaultColor ) ) ); 5345 pObj->SetMergedItemSet(aSet); 5346 } 5347 5348 //Means that fBehindDocument is set 5349 if (GetPropertyValue(DFF_Prop_fPrint) & 0x20) 5350 pImpRec->bDrawHell = sal_True; 5351 else 5352 pImpRec->bDrawHell = sal_False; 5353 if (GetPropertyValue(DFF_Prop_fPrint) & 0x02) 5354 pImpRec->bHidden = sal_True; 5355 pTextImpRec->bDrawHell = pImpRec->bDrawHell; 5356 pTextImpRec->bHidden = pImpRec->bHidden; 5357 pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 ); 5358 pTextImpRec->nNextShapeId=pImpRec->nNextShapeId; 5359 5360 if ( nTextId ) 5361 { 5362 pTextImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 ); 5363 pTextImpRec->aTextId.nSequence = (sal_uInt16)nTextId; 5364 } 5365 5366 pTextImpRec->nDxWrapDistLeft = GetPropertyValue( 5367 DFF_Prop_dxWrapDistLeft, 114935L ) / 635L; 5368 pTextImpRec->nDyWrapDistTop = GetPropertyValue( 5369 DFF_Prop_dyWrapDistTop, 0 ) / 635L; 5370 pTextImpRec->nDxWrapDistRight = GetPropertyValue( 5371 DFF_Prop_dxWrapDistRight, 114935L ) / 635L; 5372 pTextImpRec->nDyWrapDistBottom = GetPropertyValue( 5373 DFF_Prop_dyWrapDistBottom, 0 ) / 635L; 5374 // 16.16 fraction times total image width or height, as appropriate. 5375 5376 if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt)) 5377 { 5378 delete pTextImpRec->pWrapPolygon; 5379 sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert; 5380 rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert; 5381 if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4))) 5382 { 5383 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert); 5384 for (sal_uInt16 i = 0; i < nNumElemVert; ++i) 5385 { 5386 sal_Int32 nX, nY; 5387 if (nElemSizeVert == 8) 5388 rSt >> nX >> nY; 5389 else 5390 { 5391 sal_Int16 nSmallX, nSmallY; 5392 rSt >> nSmallX >> nSmallY; 5393 nX = nSmallX; 5394 nY = nSmallY; 5395 } 5396 (*(pTextImpRec->pWrapPolygon))[i].X() = nX; 5397 (*(pTextImpRec->pWrapPolygon))[i].Y() = nY; 5398 } 5399 } 5400 } 5401 5402 pImpRec->nCropFromTop = GetPropertyValue( 5403 DFF_Prop_cropFromTop, 0 ); 5404 pImpRec->nCropFromBottom = GetPropertyValue( 5405 DFF_Prop_cropFromBottom, 0 ); 5406 pImpRec->nCropFromLeft = GetPropertyValue( 5407 DFF_Prop_cropFromLeft, 0 ); 5408 pImpRec->nCropFromRight = GetPropertyValue( 5409 DFF_Prop_cropFromRight, 0 ); 5410 5411 pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false; 5412 pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false; 5413 5414 sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash ); 5415 pImpRec->eLineStyle = (nLineFlags & 8) 5416 ? (MSO_LineStyle)GetPropertyValue( 5417 DFF_Prop_lineStyle, 5418 mso_lineSimple ) 5419 : (MSO_LineStyle)USHRT_MAX; 5420 pTextImpRec->eLineStyle = pImpRec->eLineStyle; 5421 5422 if( pImpRec->nShapeId ) 5423 { 5424 // Import-Record-Liste ergaenzen 5425 if( pOrgObj ) 5426 { 5427 pImpRec->pObj = pOrgObj; 5428 rImportData.aRecords.Insert( pImpRec ); 5429 } 5430 5431 if( pTextObj && (pOrgObj != pTextObj) ) 5432 { 5433 // Modify ShapeId (must be unique) 5434 pImpRec->nShapeId |= 0x8000000; 5435 pTextImpRec->pObj = pTextObj; 5436 rImportData.aRecords.Insert( pTextImpRec ); 5437 } 5438 5439 // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen 5440 /*Only store objects which are not deep inside the tree*/ 5441 if( ( rObjData.nCalledByGroup == 0 ) 5442 || 5443 ( (rObjData.nSpFlags & SP_FGROUP) 5444 && (rObjData.nCalledByGroup < 2) ) 5445 ) 5446 StoreShapeOrder( pImpRec->nShapeId, 5447 ( ( (sal_uLong)pImpRec->aTextId.nTxBxS ) << 16 ) 5448 + pImpRec->aTextId.nSequence, pObj ); 5449 } 5450 else 5451 delete pImpRec; 5452 } 5453 5454 return pObj; 5455 }; 5456 5457 void SvxMSDffManager::StoreShapeOrder(sal_uLong nId, 5458 sal_uLong nTxBx, 5459 SdrObject* pObject, 5460 SwFlyFrmFmt* pFly, 5461 short nHdFtSection) const 5462 { 5463 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5464 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5465 { 5466 SvxMSDffShapeOrder& rOrder 5467 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5468 5469 if( rOrder.nShapeId == nId ) 5470 { 5471 rOrder.nTxBxComp = nTxBx; 5472 rOrder.pObj = pObject; 5473 rOrder.pFly = pFly; 5474 rOrder.nHdFtSection = nHdFtSection; 5475 } 5476 } 5477 } 5478 5479 5480 void SvxMSDffManager::ExchangeInShapeOrder( SdrObject* pOldObject, 5481 sal_uLong nTxBx, 5482 SwFlyFrmFmt* pFly, 5483 SdrObject* pObject) const 5484 { 5485 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5486 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5487 { 5488 SvxMSDffShapeOrder& rOrder 5489 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5490 5491 if( rOrder.pObj == pOldObject ) 5492 { 5493 rOrder.pFly = pFly; 5494 rOrder.pObj = pObject; 5495 rOrder.nTxBxComp = nTxBx; 5496 } 5497 } 5498 } 5499 5500 5501 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const 5502 { 5503 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5504 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5505 { 5506 SvxMSDffShapeOrder& rOrder 5507 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5508 5509 if( rOrder.pObj == pObject ) 5510 { 5511 rOrder.pObj = 0; 5512 rOrder.pFly = 0; 5513 rOrder.nTxBxComp = 0; 5514 } 5515 } 5516 } 5517 5518 5519 5520 5521 //--------------------------------------------------------------------------- 5522 // Hilfs Deklarationen 5523 //--------------------------------------------------------------------------- 5524 5525 /*struct SvxMSDffBLIPInfo -> in's Header-File 5526 { 5527 sal_uInt16 nBLIPType; // Art des BLIP: z.B. 6 fuer PNG 5528 sal_uLong nFilePos; // Offset des BLIP im Daten-Stream 5529 sal_uLong nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt 5530 SvxMSDffBLIPInfo(sal_uInt16 nBType, sal_uLong nFPos, sal_uLong nBSize): 5531 nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){} 5532 }; 5533 */ 5534 5535 SV_IMPL_PTRARR( SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr ); 5536 5537 SV_IMPL_PTRARR( SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr ); 5538 5539 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr ); 5540 5541 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr ); 5542 5543 5544 // Liste aller SvxMSDffImportRec fuer eine Gruppe 5545 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr) 5546 5547 //--------------------------------------------------------------------------- 5548 // exportierte Klasse: oeffentliche Methoden 5549 //--------------------------------------------------------------------------- 5550 5551 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_, 5552 const String& rBaseURL, 5553 long nOffsDgg_, 5554 SvStream* pStData_, 5555 SdrModel* pSdrModel_,// s. unten: SetModel() 5556 long nApplicationScale, 5557 ColorData mnDefaultColor_, 5558 sal_uLong nDefaultFontHeight_, 5559 SvStream* pStData2_, 5560 MSFilterTracer* pTracer ) 5561 :DffPropertyReader( *this ), 5562 pFormModel( NULL ), 5563 pBLIPInfos( new SvxMSDffBLIPInfos ), 5564 pShapeInfos( new SvxMSDffShapeInfos ), 5565 pShapeOrders( new SvxMSDffShapeOrders ), 5566 nDefaultFontHeight( nDefaultFontHeight_), 5567 nOffsDgg( nOffsDgg_ ), 5568 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen, 5569 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt 5570 maBaseURL( rBaseURL ), 5571 mpFidcls( NULL ), 5572 rStCtrl( rStCtrl_ ), 5573 pStData( pStData_ ), 5574 pStData2( pStData2_ ), 5575 nSvxMSDffSettings( 0 ), 5576 nSvxMSDffOLEConvFlags( 0 ), 5577 pSecPropSet( NULL ), 5578 pEscherBlipCache( NULL ), 5579 mnDefaultColor( mnDefaultColor_), 5580 mpTracer( pTracer ), 5581 mbTracing( sal_False ) 5582 { 5583 if ( mpTracer ) 5584 { 5585 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) ); 5586 aAny >>= mbTracing; 5587 } 5588 SetModel( pSdrModel_, nApplicationScale ); 5589 5590 // FilePos des/der Stream(s) merken 5591 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 5592 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 5593 5594 // Falls kein Datenstream angegeben, gehen wir davon aus, 5595 // dass die BLIPs im Steuerstream stehen. 5596 if( !pStData ) 5597 pStData = &rStCtrl; 5598 5599 SetDefaultPropSet( rStCtrl, nOffsDgg ); 5600 5601 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen 5602 GetCtrlData( nOffsDgg ); 5603 5604 // Text-Box-Story-Ketten-Infos ueberpruefen 5605 CheckTxBxStoryChain(); 5606 5607 // alte FilePos des/der Stream(s) restaurieren 5608 rStCtrl.Seek( nOldPosCtrl ); 5609 if( &rStCtrl != pStData ) 5610 pStData->Seek( nOldPosData ); 5611 } 5612 5613 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer ) 5614 :DffPropertyReader( *this ), 5615 pFormModel( NULL ), 5616 pBLIPInfos( new SvxMSDffBLIPInfos ), 5617 pShapeInfos( new SvxMSDffShapeInfos ), 5618 pShapeOrders( new SvxMSDffShapeOrders ), 5619 nDefaultFontHeight( 24 ), 5620 nOffsDgg( 0 ), 5621 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen, 5622 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt 5623 maBaseURL( rBaseURL ), 5624 mpFidcls( NULL ), 5625 rStCtrl( rStCtrl_ ), 5626 pStData( 0 ), 5627 pStData2( 0 ), 5628 nSvxMSDffSettings( 0 ), 5629 nSvxMSDffOLEConvFlags( 0 ), 5630 pSecPropSet( NULL ), 5631 pEscherBlipCache( NULL ), 5632 mnDefaultColor( COL_DEFAULT ), 5633 mpTracer( pTracer ), 5634 mbTracing( sal_False ) 5635 { 5636 if ( mpTracer ) 5637 { 5638 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) ); 5639 aAny >>= mbTracing; 5640 } 5641 SetModel( NULL, 0 ); 5642 } 5643 5644 SvxMSDffManager::~SvxMSDffManager() 5645 { 5646 if ( pEscherBlipCache ) 5647 { 5648 void* pPtr; 5649 for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() ) 5650 delete (EscherBlipCacheEntry*)pPtr; 5651 delete pEscherBlipCache; 5652 } 5653 delete pSecPropSet; 5654 delete pBLIPInfos; 5655 delete pShapeInfos; 5656 delete pShapeOrders; 5657 delete pFormModel; 5658 delete[] mpFidcls; 5659 } 5660 5661 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags ) 5662 { 5663 nOffsDgg = nOffsDgg_; 5664 pStData = pStData_; 5665 nSvxMSDffOLEConvFlags = nOleConvFlags; 5666 5667 // FilePos des/der Stream(s) merken 5668 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 5669 5670 SetDefaultPropSet( rStCtrl, nOffsDgg ); 5671 5672 // insert fidcl cluster table 5673 GetFidclData( nOffsDgg ); 5674 5675 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen 5676 GetCtrlData( nOffsDgg ); 5677 5678 // Text-Box-Story-Ketten-Infos ueberpruefen 5679 CheckTxBxStoryChain(); 5680 5681 // alte FilePos des/der Stream(s) restaurieren 5682 rStCtrl.Seek( nOldPosCtrl ); 5683 } 5684 5685 void SvxMSDffManager::SetDgContainer( SvStream& rSt ) 5686 { 5687 sal_uInt32 nFilePos = rSt.Tell(); 5688 DffRecordHeader aDgContHd; 5689 rSt >> aDgContHd; 5690 // insert this container only if there is also a DgAtom 5691 if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) ) 5692 { 5693 DffRecordHeader aRecHd; 5694 rSt >> aRecHd; 5695 sal_uInt32 nDrawingId = aRecHd.nRecInstance; 5696 maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos ); 5697 rSt.Seek( nFilePos ); 5698 } 5699 } 5700 5701 void SvxMSDffManager::GetFidclData( long nOffsDggL ) 5702 { 5703 if ( nOffsDggL ) 5704 { 5705 sal_uInt32 nDummy, nMerk = rStCtrl.Tell(); 5706 rStCtrl.Seek( nOffsDggL ); 5707 5708 DffRecordHeader aRecHd; 5709 rStCtrl >> aRecHd; 5710 5711 DffRecordHeader aDggAtomHd; 5712 if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) ) 5713 { 5714 aDggAtomHd.SeekToContent( rStCtrl ); 5715 rStCtrl >> mnCurMaxShapeId 5716 >> mnIdClusters 5717 >> nDummy 5718 >> mnDrawingsSaved; 5719 5720 if ( mnIdClusters-- > 2 ) 5721 { 5722 if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) ) 5723 { 5724 //mpFidcls = new FIDCL[ mnIdClusters ]; 5725 mpFidcls = new (std::nothrow) FIDCL[ mnIdClusters ]; 5726 if ( mpFidcls ) { 5727 for ( sal_uInt32 i = 0; i < mnIdClusters; i++ ) 5728 { 5729 rStCtrl >> mpFidcls[ i ].dgid 5730 >> mpFidcls[ i ].cspidCur; 5731 } 5732 } 5733 } 5734 } 5735 } 5736 rStCtrl.Seek( nMerk ); 5737 } 5738 } 5739 5740 void SvxMSDffManager::CheckTxBxStoryChain() 5741 { 5742 SvxMSDffShapeInfos* pOld = pShapeInfos; 5743 sal_uInt16 nCnt = pOld->Count(); 5744 pShapeInfos = new SvxMSDffShapeInfos( (nCnt < 255) 5745 ? nCnt 5746 : 255 ); 5747 // altes Info-Array ueberarbeiten 5748 // (ist sortiert nach nTxBxComp) 5749 sal_uLong nChain = ULONG_MAX; 5750 sal_uInt16 nObjMark = 0; 5751 sal_Bool bSetReplaceFALSE = sal_False; 5752 sal_uInt16 nObj; 5753 for( nObj = 0; nObj < nCnt; ++nObj ) 5754 { 5755 SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj ); 5756 if( pObj->nTxBxComp ) 5757 { 5758 pObj->bLastBoxInChain = sal_False; 5759 // Gruppenwechsel ? 5760 // --> OD 2008-07-28 #156763# 5761 // the text id also contains an internal drawing container id 5762 // to distinguish between text id of drawing objects in different 5763 // drawing containers. 5764 // if( nChain != (pObj->nTxBxComp & 0xFFFF0000) ) 5765 if( nChain != pObj->nTxBxComp ) 5766 // <-- 5767 { 5768 // voriger war letzter seiner Gruppe 5769 if( nObj ) 5770 pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True; 5771 // Merker und Hilfs-Flag zuruecksetzen 5772 nObjMark = nObj; 5773 // --> OD 2008-07-28 #156763# 5774 // nChain = pObj->nTxBxComp & 0xFFFF0000; 5775 nChain = pObj->nTxBxComp; 5776 // <-- 5777 bSetReplaceFALSE = !pObj->bReplaceByFly; 5778 } 5779 else 5780 if( !pObj->bReplaceByFly ) 5781 { 5782 // Objekt, das NICHT durch Rahmen ersetzt werden darf ? 5783 // Hilfs-Flag setzen 5784 bSetReplaceFALSE = sal_True; 5785 // ggfs Flag in Anfang der Gruppe austragen 5786 for( sal_uInt16 nObj2 = nObjMark; nObj2 < nObj; ++nObj2 ) 5787 pOld->GetObject( nObj2 )->bReplaceByFly = sal_False; 5788 } 5789 5790 if( bSetReplaceFALSE ) 5791 { 5792 pObj->bReplaceByFly = sal_False; 5793 } 5794 } 5795 // alle Shape-Info-Objekte in pShapeInfos umkopieren 5796 // (aber nach nShapeId sortieren) 5797 pObj->bSortByShapeId = sal_True; 5798 // --> OD 2008-07-28 #156763# 5799 pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000; 5800 // <-- 5801 pShapeInfos->Insert( pObj ); 5802 } 5803 // voriger war letzter seiner Gruppe 5804 if( nObj ) 5805 pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True; 5806 // urspruengliches Array freigeben, ohne Objekte zu zerstoeren 5807 pOld->Remove((sal_uInt16)0, nCnt); 5808 delete pOld; 5809 } 5810 5811 5812 /***************************************************************************** 5813 5814 Einlesen der Shape-Infos im Ctor: 5815 --------------------------------- 5816 merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos 5817 ========= ============ ============= 5818 und merken des File-Offsets fuer jedes Blip 5819 ============ 5820 ******************************************************************************/ 5821 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ ) 5822 { 5823 // Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen 5824 long nOffsDggL = nOffsDgg_; 5825 5826 // Kontroll Stream positionieren 5827 rStCtrl.Seek( nOffsDggL ); 5828 5829 sal_uInt8 nVer; 5830 sal_uInt16 nInst; 5831 sal_uInt16 nFbt; 5832 sal_uInt32 nLength; 5833 if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return; 5834 5835 sal_Bool bOk; 5836 sal_uLong nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE; 5837 5838 // Fall A: erst Drawing Group Container, dann n Mal Drawing Container 5839 if( DFF_msofbtDggContainer == nFbt ) 5840 { 5841 GetDrawingGroupContainerData( rStCtrl, nLength ); 5842 5843 rStCtrl.Seek( STREAM_SEEK_TO_END ); 5844 sal_uInt32 nMaxStrPos = rStCtrl.Tell(); 5845 5846 nPos += nLength; 5847 // --> OD 2008-07-28 #156763# 5848 unsigned long nDrawingContainerId = 1; 5849 // <-- 5850 do 5851 { 5852 rStCtrl.Seek( nPos ); 5853 5854 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt ); 5855 5856 if( !bOk ) 5857 { 5858 nPos++; // ????????? TODO: trying to get an one-hit wonder, this code code should be rewritten... 5859 rStCtrl.Seek( nPos ); 5860 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) 5861 && ( DFF_msofbtDgContainer == nFbt ); 5862 } 5863 if( bOk ) 5864 { 5865 // --> OD 2008-07-28 #156763# 5866 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId ); 5867 // <-- 5868 } 5869 nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5870 // --> OD 2008-07-28 #156763# 5871 ++nDrawingContainerId; 5872 // <-- 5873 } 5874 while( ( rStCtrl.GetError() == 0 ) && ( nPos < nMaxStrPos ) && bOk ); 5875 } 5876 } 5877 5878 5879 // ab hier: Drawing Group Container d.h. Dokument - weit gueltige Daten 5880 // ======================= ======== 5881 // 5882 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, sal_uLong nLenDgg ) 5883 { 5884 sal_uInt8 nVer; 5885 sal_uInt16 nInst; 5886 sal_uInt16 nFbt; 5887 sal_uInt32 nLength; 5888 5889 sal_uLong nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0; 5890 5891 // Nach einem BStore Container suchen 5892 do 5893 { 5894 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5895 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5896 if( DFF_msofbtBstoreContainer == nFbt ) 5897 { 5898 nLenBStoreCont = nLength; break; 5899 } 5900 rSt.SeekRel( nLength ); 5901 } 5902 while( nRead < nLenDgg ); 5903 5904 if( !nLenBStoreCont ) return; 5905 5906 // Im BStore Container alle Header der Container und Atome auslesen und die 5907 // relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen. 5908 // Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit. 5909 5910 const sal_uLong nSkipBLIPLen = 20; // bis zu nBLIPLen zu ueberspringende Bytes 5911 const sal_uLong nSkipBLIPPos = 4; // dahinter bis zu nBLIPPos zu skippen 5912 5913 sal_uInt32 nBLIPLen = 0, nBLIPPos = 0; 5914 5915 nRead = 0; 5916 do 5917 { 5918 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5919 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5920 if( DFF_msofbtBSE == nFbt ) 5921 { 5922 nLenFBSE = nLength; 5923 // ist FBSE gross genug fuer unsere Daten 5924 sal_Bool bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE ); 5925 5926 if( bOk ) 5927 { 5928 rSt.SeekRel( nSkipBLIPLen ); 5929 rSt >> nBLIPLen; 5930 rSt.SeekRel( nSkipBLIPPos ); 5931 rSt >> nBLIPPos; 5932 bOk = rSt.GetError() == 0; 5933 5934 nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4; 5935 } 5936 5937 if( bOk ) 5938 { 5939 // Besonderheit: 5940 // Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist, 5941 // nehmen wir an, dass das Bild IM FBSE drin steht! 5942 if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) ) 5943 nBLIPPos = rSt.Tell() + 4; 5944 5945 // Das hat ja fein geklappt! 5946 // Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben. 5947 nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell()); 5948 5949 if( USHRT_MAX == nBLIPCount ) 5950 nBLIPCount = 1; 5951 else 5952 nBLIPCount++; 5953 5954 // Jetzt die Infos fuer spaetere Zugriffe speichern 5955 pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ), 5956 pBLIPInfos->Count() ); 5957 } 5958 } 5959 rSt.SeekRel( nLength ); 5960 } 5961 while( nRead < nLenBStoreCont ); 5962 } 5963 5964 5965 // ab hier: Drawing Container d.h. Seiten (Blatt, Dia) - weit gueltige Daten 5966 // ================= ====== 5967 // 5968 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, sal_uLong nLenDg, 5969 const unsigned long nDrawingContainerId ) 5970 { 5971 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 5972 5973 sal_uLong nReadDg = 0; 5974 5975 // Wir stehen in einem Drawing Container (je einer pro Seite) 5976 // und muessen nun 5977 // alle enthaltenen Shape Group Container abklappern 5978 do 5979 { 5980 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5981 nReadDg += DFF_COMMON_RECORD_HEADER_SIZE; 5982 // Patriarch gefunden (der oberste Shape Group Container) ? 5983 if( DFF_msofbtSpgrContainer == nFbt ) 5984 { 5985 if(!this->GetShapeGroupContainerData( rSt, nLength, sal_True, nDrawingContainerId )) return; 5986 } 5987 else 5988 // blanker Shape Container ? (ausserhalb vom Shape Group Container) 5989 if( DFF_msofbtSpContainer == nFbt ) 5990 { 5991 if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return; 5992 } 5993 else 5994 rSt.SeekRel( nLength ); 5995 nReadDg += nLength; 5996 } 5997 while( nReadDg < nLenDg ); 5998 } 5999 6000 sal_Bool SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt, 6001 sal_uLong nLenShapeGroupCont, 6002 sal_Bool bPatriarch, 6003 const unsigned long nDrawingContainerId ) 6004 { 6005 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 6006 long nStartShapeGroupCont = rSt.Tell(); 6007 // Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite) 6008 // und muessen nun 6009 // alle enthaltenen Shape Container abklappern 6010 sal_Bool bFirst = !bPatriarch; 6011 sal_uLong nReadSpGrCont = 0; 6012 do 6013 { 6014 if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) ) 6015 return sal_False; 6016 nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE; 6017 // Shape Container ? 6018 if( DFF_msofbtSpContainer == nFbt ) 6019 { 6020 sal_uLong nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX; 6021 if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) ) 6022 return sal_False; 6023 bFirst = sal_False; 6024 } 6025 else 6026 // eingeschachtelter Shape Group Container ? 6027 if( DFF_msofbtSpgrContainer == nFbt ) 6028 { 6029 if ( !this->GetShapeGroupContainerData( rSt, nLength, sal_False, nDrawingContainerId ) ) 6030 return sal_False; 6031 } 6032 else 6033 rSt.SeekRel( nLength ); 6034 nReadSpGrCont += nLength; 6035 } 6036 while( nReadSpGrCont < nLenShapeGroupCont ); 6037 // den Stream wieder korrekt positionieren 6038 rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont ); 6039 return sal_True; 6040 } 6041 6042 sal_Bool SvxMSDffManager::GetShapeContainerData( SvStream& rSt, 6043 sal_uLong nLenShapeCont, 6044 sal_uLong nPosGroup, 6045 const unsigned long nDrawingContainerId ) 6046 { 6047 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 6048 long nStartShapeCont = rSt.Tell(); 6049 // Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group) 6050 // und muessen nun 6051 // die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe) 6052 // und den ersten BStore Verweis (falls vorhanden) entnehmen 6053 sal_uLong nLenShapePropTbl = 0; 6054 sal_uLong nReadSpCont = 0; 6055 6056 // File Offset des Shape-Containers bzw. der Gruppe(!) vermerken 6057 // 6058 sal_uLong nStartOffs = (ULONG_MAX > nPosGroup) ? 6059 nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE; 6060 SvxMSDffShapeInfo aInfo( nStartOffs ); 6061 6062 // duerfte das Shape durch einen Rahmen ersetzt werden ? 6063 // (vorausgesetzt, es zeigt sich, dass es eine TextBox ist, 6064 // und der Text nicht gedreht ist) 6065 sal_Bool bCanBeReplaced = (ULONG_MAX > nPosGroup) ? sal_False : sal_True; 6066 6067 // wir wissen noch nicht, ob es eine TextBox ist 6068 MSO_SPT eShapeType = mso_sptNil; 6069 MSO_WrapMode eWrapMode = mso_wrapSquare; 6070 // sal_Bool bIsTextBox = sal_False; 6071 6072 // Shape analysieren 6073 // 6074 do 6075 { 6076 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return sal_False; 6077 nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE; 6078 // FSP ? 6079 if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) ) 6080 { 6081 // Wir haben den FSP gefunden: Shape Typ und Id vermerken! 6082 eShapeType = (MSO_SPT)nInst; 6083 rSt >> aInfo.nShapeId; 6084 rSt.SeekRel( nLength - 4 ); 6085 nReadSpCont += nLength; 6086 } 6087 else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ? 6088 { 6089 // Wir haben die Property Table gefunden: 6090 // nach der Blip Property suchen! 6091 sal_uLong nPropRead = 0; 6092 sal_uInt16 nPropId; 6093 sal_uInt32 nPropVal; 6094 nLenShapePropTbl = nLength; 6095 // sal_uInt32 nPropCount = nInst; 6096 long nStartShapePropTbl = rSt.Tell(); 6097 // sal_uInt32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6); 6098 do 6099 { 6100 rSt >> nPropId 6101 >> nPropVal; 6102 nPropRead += 6; 6103 6104 switch( nPropId ) 6105 { 6106 case DFF_Prop_txflTextFlow : 6107 //Writer can now handle vertical textflows in its 6108 //native frames, to only need to do this for the 6109 //other two formats 6110 6111 //Writer will handle all textflow except BtoT 6112 if (GetSvxMSDffSettings() & 6113 (SVXMSDFF_SETTINGS_IMPORT_PPT | 6114 SVXMSDFF_SETTINGS_IMPORT_EXCEL)) 6115 { 6116 if( 0 != nPropVal ) 6117 bCanBeReplaced = false; 6118 } 6119 else if ( 6120 (nPropVal != mso_txflHorzN) && 6121 (nPropVal != mso_txflTtoBA) 6122 ) 6123 { 6124 bCanBeReplaced = false; 6125 } 6126 break; 6127 case DFF_Prop_cdirFont : 6128 //Writer can now handle right to left and left 6129 //to right in its native frames, so only do 6130 //this for the other two formats. 6131 if (GetSvxMSDffSettings() & 6132 (SVXMSDFF_SETTINGS_IMPORT_PPT | 6133 SVXMSDFF_SETTINGS_IMPORT_EXCEL)) 6134 { 6135 if( 0 != nPropVal ) 6136 bCanBeReplaced = sal_False; 6137 } 6138 break; 6139 case DFF_Prop_Rotation : 6140 if( 0 != nPropVal ) 6141 bCanBeReplaced = sal_False; 6142 break; 6143 6144 case DFF_Prop_gtextFStrikethrough : 6145 if( ( 0x20002000 & nPropVal ) == 0x20002000 ) 6146 bCanBeReplaced = sal_False; 6147 break; 6148 6149 case DFF_Prop_fc3DLightFace : 6150 if( ( 0x00080008 & nPropVal ) == 0x00080008 ) 6151 bCanBeReplaced = sal_False; 6152 break; 6153 6154 case DFF_Prop_WrapText : 6155 eWrapMode = (MSO_WrapMode)nPropVal; 6156 break; 6157 6158 default: 6159 { 6160 // Bit gesetzt und gueltig? 6161 if( 0x4000 == ( nPropId & 0xC000 ) ) 6162 { 6163 // Blip Property gefunden: BStore Idx vermerken! 6164 nPropRead = nLenShapePropTbl; 6165 } 6166 else if( 0x8000 & nPropId ) 6167 { 6168 // komplexe Prop gefunden: 6169 // Laenge ist immer 6, nur die Laenge der nach der 6170 // eigentlichen Prop-Table anhaengenden Extra-Daten 6171 // ist unterschiedlich 6172 nPropVal = 6; 6173 } 6174 } 6175 break; 6176 } 6177 6178 /* 6179 //JP 21.04.99: Bug 64510 6180 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge 6181 // Performance einbussen hat. 6182 6183 if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig? 6184 { 6185 // Blip Property gefunden: BStore Idx vermerken! 6186 aInfo.nBStoreIdx = nPropVal; // Index im BStore Container 6187 break; 6188 } 6189 else 6190 if( ( ( (DFF_Prop_txflTextFlow == nPropId) 6191 || (DFF_Prop_Rotation == nPropId) 6192 || (DFF_Prop_cdirFont == nPropId) ) 6193 && (0 != nPropVal) ) 6194 6195 || ( (DFF_Prop_gtextFStrikethrough == nPropId) 6196 && ( (0x20002000 & nPropVal) == 0x20002000) ) // also DFF_Prop_gtextFVertical 6197 || ( (DFF_Prop_fc3DLightFace == nPropId) 6198 && ( (0x00080008 & nPropVal) == 0x00080008) ) // also DFF_Prop_f3D 6199 ) 6200 { 6201 bCanBeReplaced = sal_False; // Mist: gedrehter Text oder 3D-Objekt! 6202 } 6203 else 6204 if( DFF_Prop_WrapText == nPropId ) 6205 { 6206 eWrapMode = (MSO_WrapMode)nPropVal; 6207 } 6208 //////////////////////////////////////////////////////////////// 6209 //////////////////////////////////////////////////////////////// 6210 // keine weitere Property-Auswertung: folge beim Shape-Import // 6211 //////////////////////////////////////////////////////////////// 6212 //////////////////////////////////////////////////////////////// 6213 else 6214 if( 0x8000 & nPropId ) 6215 { 6216 // komplexe Prop gefunden: Laenge lesen und ueberspringen 6217 if(!SkipBytes( rSt, nPropVal )) return sal_False; 6218 nPropRead += nPropVal; 6219 } 6220 */ 6221 } 6222 while( nPropRead < nLenShapePropTbl ); 6223 rSt.Seek( nStartShapePropTbl + nLenShapePropTbl ); 6224 nReadSpCont += nLenShapePropTbl; 6225 } 6226 else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) ) // Text-Box-Story-Eintrag gefunden 6227 { 6228 rSt >> aInfo.nTxBxComp; 6229 // --> OD 2008-07-28 #156763# 6230 // Add internal drawing container id to text id. 6231 // Note: The text id uses the first two bytes, while the internal 6232 // drawing container id used the second two bytes. 6233 aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) + 6234 nDrawingContainerId; 6235 DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId, 6236 "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." ); 6237 // <-- 6238 } 6239 else 6240 { 6241 rSt.SeekRel( nLength ); 6242 nReadSpCont += nLength; 6243 } 6244 } 6245 while( nReadSpCont < nLenShapeCont ); 6246 6247 // 6248 // Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern 6249 // 6250 if( aInfo.nShapeId ) 6251 { 6252 // fuer Textboxen ggfs. ersetzen durch Rahmen erlauben 6253 if( bCanBeReplaced 6254 && aInfo.nTxBxComp 6255 && ( 6256 ( eShapeType == mso_sptTextSimple ) 6257 || ( eShapeType == mso_sptTextBox ) 6258 || ( ( ( eShapeType == mso_sptRectangle ) 6259 || ( eShapeType == mso_sptRoundRectangle ) 6260 ) 6261 ) ) ) 6262 { 6263 aInfo.bReplaceByFly = sal_True; 6264 } 6265 pShapeInfos->Insert( new SvxMSDffShapeInfo( aInfo ) ); 6266 pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ), 6267 pShapeOrders->Count() ); 6268 } 6269 6270 // und den Stream wieder korrekt positionieren 6271 rSt.Seek( nStartShapeCont + nLenShapeCont ); 6272 return sal_True; 6273 } 6274 6275 6276 6277 /***************************************************************************** 6278 6279 Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id) 6280 ---------------------------------- 6281 ******************************************************************************/ 6282 sal_Bool SvxMSDffManager::GetShape(sal_uLong nId, SdrObject*& rpShape, 6283 SvxMSDffImportData& rData) 6284 { 6285 SvxMSDffShapeInfo aTmpRec(0, nId); 6286 aTmpRec.bSortByShapeId = sal_True; 6287 6288 sal_uInt16 nFound; 6289 if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) ) 6290 { 6291 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound ); 6292 6293 // eventuell altes Errorflag loeschen 6294 if( rStCtrl.GetError() ) 6295 rStCtrl.ResetError(); 6296 // FilePos des/der Stream(s) merken 6297 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 6298 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 6299 // das Shape im Steuer Stream anspringen 6300 rStCtrl.Seek( rInfo.nFilePos ); 6301 6302 // Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt! 6303 if( rStCtrl.GetError() ) 6304 rStCtrl.ResetError(); 6305 else 6306 rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect ); 6307 6308 // alte FilePos des/der Stream(s) restaurieren 6309 rStCtrl.Seek( nOldPosCtrl ); 6310 if( &rStCtrl != pStData ) 6311 pStData->Seek( nOldPosData ); 6312 return ( 0 != rpShape ); 6313 } 6314 return sal_False; 6315 } 6316 6317 6318 6319 /* Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr) 6320 --------------------------------- 6321 ******************************************************************************/ 6322 sal_Bool SvxMSDffManager::GetBLIP( sal_uLong nIdx_, Graphic& rData, Rectangle* pVisArea ) const 6323 { 6324 sal_Bool bOk = sal_False; // Ergebnisvariable initialisieren 6325 if ( pStData ) 6326 { 6327 // check if a graphic for this blipId is already imported 6328 if ( nIdx_ && pEscherBlipCache ) 6329 { 6330 EscherBlipCacheEntry* pEntry; 6331 for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry; 6332 pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() ) 6333 { 6334 if ( pEntry->nBlip == nIdx_ ) 6335 { /* if this entry is available, then it should be possible 6336 to get the Graphic via GraphicObject */ 6337 GraphicObject aGraphicObject( pEntry->aUniqueID ); 6338 rData = aGraphicObject.GetGraphic(); 6339 if ( rData.GetType() != GRAPHIC_NONE ) 6340 bOk = sal_True; 6341 else 6342 delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove(); 6343 break; 6344 } 6345 } 6346 } 6347 if ( !bOk ) 6348 { 6349 sal_uInt16 nIdx = sal_uInt16( nIdx_ ); 6350 if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return sal_False; 6351 6352 // eventuell alte(s) Errorflag(s) loeschen 6353 if( rStCtrl.GetError() ) 6354 rStCtrl.ResetError(); 6355 if( ( &rStCtrl != pStData ) 6356 && pStData->GetError() ) 6357 pStData->ResetError(); 6358 6359 // FilePos des/der Stream(s) merken 6360 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 6361 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 6362 6363 // passende Info-Struct aus unserem Pointer Array nehmen 6364 SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ]; 6365 6366 // das BLIP Atom im Daten Stream anspringen 6367 pStData->Seek( rInfo.nFilePos ); 6368 // ggfs. Fehlerstatus zuruecksetzen 6369 if( pStData->GetError() ) 6370 pStData->ResetError(); 6371 else 6372 bOk = GetBLIPDirect( *pStData, rData, pVisArea ); 6373 if( pStData2 && !bOk ) 6374 { 6375 // Fehler, aber zweite Chance: es gibt noch einen zweiten 6376 // Datenstream, in dem die Grafik liegen koennte! 6377 if( pStData2->GetError() ) 6378 pStData2->ResetError(); 6379 sal_uLong nOldPosData2 = pStData2->Tell(); 6380 // das BLIP Atom im zweiten Daten Stream anspringen 6381 pStData2->Seek( rInfo.nFilePos ); 6382 // ggfs. Fehlerstatus zuruecksetzen 6383 if( pStData2->GetError() ) 6384 pStData2->ResetError(); 6385 else 6386 bOk = GetBLIPDirect( *pStData2, rData, pVisArea ); 6387 // alte FilePos des zweiten Daten-Stream restaurieren 6388 pStData2->Seek( nOldPosData2 ); 6389 } 6390 // alte FilePos des/der Stream(s) restaurieren 6391 rStCtrl.Seek( nOldPosCtrl ); 6392 if( &rStCtrl != pStData ) 6393 pStData->Seek( nOldPosData ); 6394 6395 if ( bOk ) 6396 { 6397 // create new BlipCacheEntry for this graphic 6398 GraphicObject aGraphicObject( rData ); 6399 if ( !pEscherBlipCache ) 6400 const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List(); 6401 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() ); 6402 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND ); 6403 } 6404 } 6405 } 6406 return bOk; 6407 } 6408 6409 /* Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream) 6410 --------------------------------- 6411 ******************************************************************************/ 6412 sal_Bool SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const 6413 { 6414 sal_uLong nOldPos = rBLIPStream.Tell(); 6415 6416 int nRes = GRFILTER_OPENERROR; // Fehlervariable initialisieren 6417 6418 // nachschauen, ob es sich auch wirklich um ein BLIP handelt 6419 sal_uInt32 nLength; 6420 sal_uInt16 nInst, nFbt( 0 ); 6421 sal_uInt8 nVer; 6422 if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) ) 6423 { 6424 Size aMtfSize100; 6425 sal_Bool bMtfBLIP = sal_False; 6426 sal_Bool bZCodecCompression = sal_False; 6427 // Nun exakt auf den Beginn der eingebetteten Grafik positionieren 6428 sal_uLong nSkip = ( nInst & 0x0001 ) ? 32 : 16; 6429 6430 switch( nInst & 0xFFFE ) 6431 { 6432 case 0x216 : // Metafile header then compressed WMF 6433 case 0x3D4 : // Metafile header then compressed EMF 6434 case 0x542 : // Metafile hd. then compressed PICT 6435 { 6436 rBLIPStream.SeekRel( nSkip + 20 ); 6437 6438 // read in size of metafile in EMUS 6439 rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height(); 6440 6441 // scale to 1/100mm 6442 aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360; 6443 6444 if ( pVisArea ) // seem that we currently are skipping the visarea position 6445 *pVisArea = Rectangle( Point(), aMtfSize100 ); 6446 6447 // skip rest of header 6448 nSkip = 6; 6449 bMtfBLIP = bZCodecCompression = sal_True; 6450 } 6451 break; 6452 case 0x46A : // One byte tag then JPEG (= JFIF) data 6453 case 0x6E0 : // One byte tag then PNG data 6454 case 0x6E2 : // One byte tag then JPEG in CMYK color space 6455 case 0x7A8 : 6456 nSkip += 1; // One byte tag then DIB data 6457 break; 6458 } 6459 rBLIPStream.SeekRel( nSkip ); 6460 6461 SvStream* pGrStream = &rBLIPStream; 6462 SvMemoryStream* pOut = NULL; 6463 if( bZCodecCompression ) 6464 { 6465 pOut = new SvMemoryStream( 0x8000, 0x4000 ); 6466 ZCodec aZCodec( 0x8000, 0x8000 ); 6467 aZCodec.BeginCompression(); 6468 aZCodec.Decompress( rBLIPStream, *pOut ); 6469 aZCodec.EndCompression(); 6470 pOut->Seek( STREAM_SEEK_TO_BEGIN ); 6471 pOut->SetResizeOffset( 0 ); // sj: #i102257# setting ResizeOffset of 0 prevents from seeking 6472 // behind the stream end (allocating too much memory) 6473 pGrStream = pOut; 6474 } 6475 6476 //#define DBG_EXTRACTGRAPHICS 6477 #ifdef DBG_EXTRACTGRAPHICS 6478 6479 static sal_Int32 nCount; 6480 6481 String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) ); 6482 aFileName.Append( String::CreateFromInt32( nCount++ ) ); 6483 switch( nInst &~ 1 ) 6484 { 6485 case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break; 6486 case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break; 6487 case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break; 6488 case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break; 6489 case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break; 6490 case 0x6e2 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break; 6491 case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break; 6492 } 6493 6494 String aURLStr; 6495 6496 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) ) 6497 { 6498 INetURLObject aURL( aURLStr ); 6499 6500 aURL.removeSegment(); 6501 aURL.removeFinalSlash(); 6502 aURL.Append( aFileName ); 6503 6504 SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE ); 6505 6506 if( pDbgOut ) 6507 { 6508 if ( bZCodecCompression ) 6509 { 6510 pOut->Seek( STREAM_SEEK_TO_END ); 6511 pDbgOut->Write( pOut->GetData(), pOut->Tell() ); 6512 pOut->Seek( STREAM_SEEK_TO_BEGIN ); 6513 } 6514 else 6515 { 6516 sal_Int32 nDbgLen = nLength - nSkip; 6517 if ( nDbgLen ) 6518 { 6519 sal_Char* pDat = new sal_Char[ nDbgLen ]; 6520 pGrStream->Read( pDat, nDbgLen ); 6521 pDbgOut->Write( pDat, nDbgLen ); 6522 pGrStream->SeekRel( -nDbgLen ); 6523 delete[] pDat; 6524 } 6525 } 6526 6527 delete pDbgOut; 6528 } 6529 } 6530 #endif 6531 6532 if( ( nInst & 0xFFFE ) == 0x7A8 ) 6533 { // DIBs direkt holen 6534 Bitmap aNew; 6535 if( aNew.Read( *pGrStream, sal_False ) ) 6536 { 6537 rData = Graphic( aNew ); 6538 nRes = GRFILTER_OK; 6539 } 6540 } 6541 else 6542 { // und unsere feinen Filter darauf loslassen 6543 GraphicFilter* pGF = GraphicFilter::GetGraphicFilter(); 6544 String aEmptyStr; 6545 nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW ); 6546 6547 // SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems, 6548 // then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the 6549 // scaling has been implemented does not happen anymore. 6550 // 6551 // For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the 6552 // dxarray is empty (this has been solved in wmf/emf but not for pict) 6553 if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) ) 6554 { 6555 if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) ) 6556 { // #75956#, scaling does not work properly, if the graphic is less than 1cm 6557 GDIMetaFile aMtf( rData.GetGDIMetaFile() ); 6558 const Size aOldSize( aMtf.GetPrefSize() ); 6559 6560 if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) && 6561 aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) ) 6562 { 6563 aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(), 6564 (double) aMtfSize100.Height() / aOldSize.Height() ); 6565 aMtf.SetPrefSize( aMtfSize100 ); 6566 aMtf.SetPrefMapMode( MAP_100TH_MM ); 6567 rData = aMtf; 6568 } 6569 } 6570 } 6571 } 6572 // ggfs. Fehlerstatus zuruecksetzen 6573 if ( ERRCODE_IO_PENDING == pGrStream->GetError() ) 6574 pGrStream->ResetError(); 6575 delete pOut; 6576 } 6577 rBLIPStream.Seek( nOldPos ); // alte FilePos des Streams restaurieren 6578 6579 return ( GRFILTER_OK == nRes ); // Ergebniss melden 6580 } 6581 6582 /* static */ 6583 sal_Bool SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn) 6584 { 6585 rRec.nFilePos = rIn.Tell(); 6586 return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer, 6587 rRec.nRecInstance, 6588 rRec.nRecType, 6589 rRec.nRecLen ); 6590 } 6591 6592 6593 /* auch static */ 6594 sal_Bool SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt, 6595 sal_uInt8& rVer, 6596 sal_uInt16& rInst, 6597 sal_uInt16& rFbt, 6598 sal_uInt32& rLength ) 6599 { 6600 sal_uInt16 nTmp; 6601 rSt >> nTmp >> rFbt >> rLength; 6602 rVer = sal::static_int_cast< sal_uInt8 >(nTmp & 15); 6603 rInst = nTmp >> 4; 6604 if ( rLength > ( SAL_MAX_UINT32 - rSt.Tell() ) ) // preserving overflow, optimal would be to check 6605 rSt.SetError( SVSTREAM_FILEFORMAT_ERROR ); // the record size against the parent header 6606 return rSt.GetError() == 0; 6607 } 6608 6609 6610 6611 6612 sal_Bool SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, sal_uLong nDatLen, 6613 char*& rpBuff, sal_uInt32& rBuffLen ) const 6614 { 6615 if( nDatLen ) 6616 { 6617 rpBuff = new (std::nothrow) char[ nDatLen ]; 6618 rBuffLen = nDatLen; 6619 rStData.Read( rpBuff, nDatLen ); 6620 } 6621 return sal_True; 6622 } 6623 6624 sal_Bool SvxMSDffManager::ProcessClientData(SvStream& rStData, sal_uLong nDatLen, 6625 char*& rpBuff, sal_uInt32& rBuffLen ) const 6626 { 6627 if( nDatLen ) 6628 { 6629 rpBuff = new (std::nothrow) char[ nDatLen ]; 6630 if ( rpBuff ) 6631 { 6632 rBuffLen = nDatLen; 6633 rStData.Read( rpBuff, nDatLen ); 6634 } 6635 } 6636 return sal_True; 6637 } 6638 6639 6640 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ ) 6641 { 6642 return; // wird von SJ im Draw ueberladen 6643 } 6644 6645 sal_uLong SvxMSDffManager::Calc_nBLIPPos( sal_uLong nOrgVal, sal_uLong /* nStreamPos */ ) const 6646 { 6647 return nOrgVal; 6648 } 6649 6650 sal_Bool SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const 6651 { 6652 return sal_False; 6653 } 6654 6655 sal_Bool SvxMSDffManager::ShapeHasText( sal_uLong /* nShapeId */, sal_uLong /* nFilePos */ ) const 6656 { 6657 return sal_True; 6658 } 6659 6660 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup> 6661 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId, 6662 const Graphic& rGrf, 6663 const Rectangle& rBoundRect, 6664 const Rectangle& rVisArea, 6665 const int /* _nCalledByGroup */, 6666 sal_Int64 nAspect ) const 6667 // <-- 6668 { 6669 SdrObject* pRet = 0; 6670 String sStorageName; 6671 SvStorageRef xSrcStg; 6672 ErrCode nError = ERRCODE_NONE; 6673 uno::Reference < embed::XStorage > xDstStg; 6674 if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg )) 6675 pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg, 6676 rGrf, rBoundRect, rVisArea, pStData, nError, 6677 nSvxMSDffOLEConvFlags, nAspect ); 6678 return pRet; 6679 } 6680 6681 sal_Bool SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf ) 6682 { 6683 String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) ); 6684 SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream ); 6685 xStm->SetVersion( pStor->GetVersion() ); 6686 xStm->SetBufferSize( 8192 ); 6687 6688 sal_uInt16 nAspect = ASPECT_CONTENT; 6689 sal_uLong nAdviseModes = 2; 6690 6691 Impl_OlePres aEle( FORMAT_GDIMETAFILE ); 6692 // Die Groesse in 1/100 mm umrechnen 6693 // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird, 6694 // versucht SV einen BestMatchden richtigen Wert zu raten. 6695 Size aSize = rMtf.GetPrefSize(); 6696 MapMode aMMSrc = rMtf.GetPrefMapMode(); 6697 MapMode aMMDst( MAP_100TH_MM ); 6698 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst ); 6699 aEle.SetSize( aSize ); 6700 aEle.SetAspect( nAspect ); 6701 aEle.SetAdviseFlags( nAdviseModes ); 6702 aEle.SetMtf( rMtf ); 6703 aEle.Write( *xStm ); 6704 6705 xStm->SetBufferSize( 0 ); 6706 return xStm->GetError() == SVSTREAM_OK; 6707 } 6708 6709 struct ClsIDs { 6710 sal_uInt32 nId; 6711 const sal_Char* pSvrName; 6712 const sal_Char* pDspName; 6713 }; 6714 static ClsIDs aClsIDs[] = { 6715 6716 { 0x000212F0, "MSWordArt", "Microsoft Word Art" }, 6717 { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" }, 6718 6719 // MS Apps 6720 { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" }, 6721 { 0x00030001, "ExcelChart", "Microsoft Excel Chart" }, 6722 { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" }, 6723 { 0x00030003, "WordDocument", "Microsoft Word Document" }, 6724 { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" }, 6725 { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"}, 6726 { 0x00030006, "MSGraph", "Microsoft Graph" }, 6727 { 0x00030007, "MSDraw", "Microsoft Draw" }, 6728 { 0x00030008, "Note-It", "Microsoft Note-It" }, 6729 { 0x00030009, "WordArt", "Microsoft Word Art" }, 6730 { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" }, 6731 { 0x0003000b, "Equation", "Microsoft Equation Editor" }, 6732 { 0x0003000c, "Package", "Package" }, 6733 { 0x0003000d, "SoundRec", "Sound" }, 6734 { 0x0003000e, "MPlayer", "Media Player" }, 6735 // MS Demos 6736 { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" }, 6737 { 0x00030010, "Srtest", "OLE 1.0 Test Demo" }, 6738 { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" }, 6739 { 0x00030012, "OleDemo", "OLE 1.0 Demo" }, 6740 6741 // Coromandel / Dorai Swamy / 718-793-7963 6742 { 0x00030013, "CoromandelIntegra", "Coromandel Integra" }, 6743 { 0x00030014, "CoromandelObjServer","Coromandel Object Server" }, 6744 6745 // 3-d Visions Corp / Peter Hirsch / 310-325-1339 6746 { 0x00030015, "StanfordGraphics", "Stanford Graphics" }, 6747 6748 // Deltapoint / Nigel Hearne / 408-648-4000 6749 { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" }, 6750 { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" }, 6751 6752 // Corel / Richard V. Woodend / 613-728-8200 x1153 6753 { 0x00030018, "PhotoPaint", "Corel PhotoPaint" }, 6754 { 0x00030019, "CShow", "Corel Show" }, 6755 { 0x0003001a, "CorelChart", "Corel Chart" }, 6756 { 0x0003001b, "CDraw", "Corel Draw" }, 6757 6758 // Inset Systems / Mark Skiba / 203-740-2400 6759 { 0x0003001c, "HJWIN1.0", "Inset Systems" }, 6760 6761 // Mark V Systems / Mark McGraw / 818-995-7671 6762 { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" }, 6763 6764 // IdentiTech / Mike Gilger / 407-951-9503 6765 { 0x0003001e, "FYI", "IdentiTech FYI" }, 6766 { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" }, 6767 6768 // Inventa Corporation / Balaji Varadarajan / 408-987-0220 6769 { 0x00030020, "Stickynote", "Inventa Sticky Note" }, 6770 6771 // ShapeWare Corp. / Lori Pearce / 206-467-6723 6772 { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" }, 6773 { 0x00030022, "ImportServer", "Spaheware Import Server" }, 6774 6775 // test app SrTest 6776 { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" }, 6777 6778 // test app ClTest. Doesn't really work as a server but is in reg db 6779 { 0x00030025, "Cltest", "OLE 1.0 Client Test" }, 6780 6781 // Microsoft ClipArt Gallery Sherry Larsen-Holmes 6782 { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" }, 6783 // Microsoft Project Cory Reina 6784 { 0x00030027, "MSProject", "Microsoft Project" }, 6785 6786 // Microsoft Works Chart 6787 { 0x00030028, "MSWorksChart", "Microsoft Works Chart" }, 6788 6789 // Microsoft Works Spreadsheet 6790 { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" }, 6791 6792 // AFX apps - Dean McCrory 6793 { 0x0003002A, "MinSvr", "AFX Mini Server" }, 6794 { 0x0003002B, "HierarchyList", "AFX Hierarchy List" }, 6795 { 0x0003002C, "BibRef", "AFX BibRef" }, 6796 { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" }, 6797 { 0x0003002E, "TestServ", "AFX Test Server" }, 6798 6799 // Ami Pro 6800 { 0x0003002F, "AmiProDocument", "Ami Pro Document" }, 6801 6802 // WordPerfect Presentations For Windows 6803 { 0x00030030, "WPGraphics", "WordPerfect Presentation" }, 6804 { 0x00030031, "WPCharts", "WordPerfect Chart" }, 6805 6806 // MicroGrafx Charisma 6807 { 0x00030032, "Charisma", "MicroGrafx Charisma" }, 6808 { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" }, 6809 { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" }, 6810 // MicroGrafx Draw 6811 { 0x00030035, "Draw", "MicroGrafx Draw" }, 6812 // MicroGrafx Designer 6813 { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" }, 6814 6815 // STAR DIVISION 6816 // { 0x000424CA, "StarMath", "StarMath 1.0" }, 6817 { 0x00043AD2, "FontWork", "Star FontWork" }, 6818 // { 0x000456EE, "StarMath2", "StarMath 2.0" }, 6819 6820 { 0, "", "" } }; 6821 6822 6823 sal_Bool SvxMSDffManager::ConvertToOle2( SvStream& rStm, sal_uInt32 nReadLen, 6824 const GDIMetaFile * pMtf, const SotStorageRef& rDest ) 6825 { 6826 sal_Bool bMtfRead = sal_False; 6827 SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ), 6828 STREAM_WRITE| STREAM_SHARE_DENYALL ); 6829 if( xOle10Stm->GetError() ) 6830 return sal_False; 6831 6832 sal_uInt32 nType; 6833 sal_uInt32 nRecType; 6834 sal_uInt32 nStrLen; 6835 String aSvrName; 6836 sal_uInt32 nDummy0; 6837 sal_uInt32 nDummy1; 6838 sal_uInt32 nDataLen; 6839 sal_uInt8 * pData; 6840 sal_uInt32 nBytesRead = 0; 6841 do 6842 { 6843 rStm >> nType; 6844 rStm >> nRecType; 6845 rStm >> nStrLen; 6846 if( nStrLen ) 6847 { 6848 if( 0x10000L > nStrLen ) 6849 { 6850 sal_Char * pBuf = new sal_Char[ nStrLen ]; 6851 rStm.Read( pBuf, nStrLen ); 6852 aSvrName.Assign( String( pBuf, (sal_uInt16) nStrLen-1, gsl_getSystemTextEncoding() ) ); 6853 delete[] pBuf; 6854 } 6855 else 6856 break; 6857 } 6858 rStm >> nDummy0; 6859 rStm >> nDummy1; 6860 rStm >> nDataLen; 6861 6862 nBytesRead += 6 * sizeof( sal_uInt32 ) + nStrLen + nDataLen; 6863 6864 if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen ) 6865 { 6866 if( xOle10Stm.Is() ) 6867 { 6868 pData = new sal_uInt8[ nDataLen ]; 6869 if( !pData ) 6870 return sal_False; 6871 6872 rStm.Read( pData, nDataLen ); 6873 6874 // write to ole10 stream 6875 *xOle10Stm << nDataLen; 6876 xOle10Stm->Write( pData, nDataLen ); 6877 xOle10Stm = SotStorageStreamRef(); 6878 6879 // set the compobj stream 6880 ClsIDs* pIds; 6881 for( pIds = aClsIDs; pIds->nId; pIds++ ) 6882 { 6883 if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) ) 6884 break; 6885 } 6886 // SvGlobalName* pClsId = NULL; 6887 String aShort, aFull; 6888 if( pIds->nId ) 6889 { 6890 // gefunden! 6891 sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName ); 6892 rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt, 6893 String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) ); 6894 } 6895 else 6896 { 6897 sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName ); 6898 rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName ); 6899 } 6900 6901 delete[] pData; 6902 } 6903 else if( nRecType == 5 && !pMtf ) 6904 { 6905 sal_uLong nPos = rStm.Tell(); 6906 sal_uInt16 sz[4]; 6907 rStm.Read( sz, 8 ); 6908 //rStm.SeekRel( 8 ); 6909 Graphic aGraphic; 6910 if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() ) 6911 { 6912 const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile(); 6913 MakeContentStream( rDest, rMtf ); 6914 bMtfRead = sal_True; 6915 } 6916 // set behind the data 6917 rStm.Seek( nPos + nDataLen ); 6918 } 6919 else 6920 rStm.SeekRel( nDataLen ); 6921 } 6922 } while( !rStm.IsEof() && nReadLen >= nBytesRead ); 6923 6924 if( !bMtfRead && pMtf ) 6925 { 6926 MakeContentStream( rDest, *pMtf ); 6927 return sal_True; 6928 } 6929 6930 return sal_False; 6931 } 6932 6933 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName ) 6934 { 6935 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) 6936 || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) ) 6937 return "swriter"; 6938 else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) 6939 || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) ) 6940 return "scalc"; 6941 else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) 6942 || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) 6943 return "simpress"; 6944 else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) 6945 || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) 6946 return "sdraw"; 6947 else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) 6948 || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) ) 6949 return "smath"; 6950 else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) 6951 || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) 6952 return "schart"; 6953 return 0; 6954 } 6955 6956 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName ) 6957 { 6958 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) ) 6959 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) ); 6960 6961 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) ) 6962 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) ); 6963 6964 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) ) 6965 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) ); 6966 6967 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) ) 6968 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) ); 6969 6970 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) ) 6971 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) ); 6972 6973 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) 6974 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) ); 6975 6976 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) ) 6977 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) ); 6978 6979 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) 6980 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) ); 6981 6982 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) ) 6983 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) ); 6984 6985 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) ) 6986 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) ); 6987 6988 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) ) 6989 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) ); 6990 6991 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) 6992 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) ); 6993 6994 return ::rtl::OUString(); 6995 } 6996 6997 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > SvxMSDffManager::CheckForConvertToSOObj( sal_uInt32 nConvertFlags, 6998 SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage, 6999 const Graphic& rGrf, 7000 const Rectangle& rVisArea ) 7001 { 7002 uno::Reference < embed::XEmbeddedObject > xObj; 7003 SvGlobalName aStgNm = rSrcStg.GetClassName(); 7004 const char* pName = GetInternalServerName_Impl( aStgNm ); 7005 String sStarName; 7006 if ( pName ) 7007 sStarName = String::CreateFromAscii( pName ); 7008 else if ( nConvertFlags ) 7009 { 7010 static struct _ObjImpType 7011 { 7012 sal_uInt32 nFlag; 7013 const char* pFactoryNm; 7014 // GlobalNameId 7015 sal_uInt32 n1; 7016 sal_uInt16 n2, n3; 7017 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15; 7018 } aArr[] = { 7019 { OLE_MATHTYPE_2_STARMATH, "smath", 7020 0x0002ce02L, 0x0000, 0x0000, 7021 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7022 { OLE_MATHTYPE_2_STARMATH, "smath", 7023 0x00021700L, 0x0000, 0x0000, 7024 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7025 { OLE_WINWORD_2_STARWRITER, "swriter", 7026 0x00020906L, 0x0000, 0x0000, 7027 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7028 { OLE_EXCEL_2_STARCALC, "scalc", // Excel table 7029 0x00020810L, 0x0000, 0x0000, 7030 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7031 { OLE_EXCEL_2_STARCALC, "scalc", // Excel chart 7032 0x00020820L, 0x0000, 0x0000, 7033 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7034 // 114465: additional Excel OLE chart classId to above. 7035 { OLE_EXCEL_2_STARCALC, "scalc", 7036 0x00020821L, 0x0000, 0x0000, 7037 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7038 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint presentation 7039 0x64818d10L, 0x4f9b, 0x11cf, 7040 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 }, 7041 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint slide 7042 0x64818d11L, 0x4f9b, 0x11cf, 7043 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 }, 7044 { 0, 0, 7045 0, 0, 0, 7046 0, 0, 0, 0, 0, 0, 0, 0 } 7047 }; 7048 7049 for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr ) 7050 { 7051 if( nConvertFlags & pArr->nFlag ) 7052 { 7053 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3, 7054 pArr->b8, pArr->b9, pArr->b10, pArr->b11, 7055 pArr->b12, pArr->b13, pArr->b14, pArr->b15 ); 7056 7057 if ( aStgNm == aTypeName ) 7058 { 7059 sStarName = String::CreateFromAscii( pArr->pFactoryNm ); 7060 break; 7061 } 7062 } 7063 } 7064 } 7065 7066 if ( sStarName.Len() ) 7067 { 7068 //TODO/MBA: check if (and when) storage and stream will be destroyed! 7069 const SfxFilter* pFilter = 0; 7070 SvMemoryStream* pStream = new SvMemoryStream; 7071 if ( pName ) 7072 { 7073 // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also 7074 SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ ); 7075 *xStr >> *pStream; 7076 } 7077 else 7078 { 7079 SfxFilterMatcher aMatch( sStarName ); 7080 SotStorageRef xStorage = new SotStorage( sal_False, *pStream ); 7081 rSrcStg.CopyTo( xStorage ); 7082 xStorage->Commit(); 7083 xStorage.Clear(); 7084 String aType = SfxFilter::GetTypeFromStorage( rSrcStg ); 7085 if ( aType.Len() ) 7086 pFilter = aMatch.GetFilter4EA( aType ); 7087 } 7088 7089 if ( pName || pFilter ) 7090 { 7091 //Reuse current ole name 7092 String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj))); 7093 aDstStgName += String::CreateFromInt32(nMSOleObjCntr); 7094 7095 ::rtl::OUString aFilterName; 7096 if ( pFilter ) 7097 aFilterName = pFilter->GetName(); 7098 else 7099 aFilterName = GetFilterNameFromClassID_Impl( aStgNm ); 7100 7101 uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2); 7102 aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) ); 7103 uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream ); 7104 aMedium[0].Value <<= xStream; 7105 aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 7106 aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ); 7107 7108 if ( aFilterName.getLength() ) 7109 { 7110 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); 7111 aMedium[2].Value <<= aFilterName; 7112 } 7113 7114 ::rtl::OUString aName( aDstStgName ); 7115 comphelper::EmbeddedObjectContainer aCnt( rDestStorage ); 7116 xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); 7117 7118 if ( !xObj.is() ) 7119 { 7120 if( aFilterName.getLength() ) 7121 { 7122 // throw the filter parameter away as workaround 7123 aMedium.realloc( 2 ); 7124 xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); 7125 } 7126 7127 if ( !xObj.is() ) 7128 return xObj; 7129 } 7130 7131 // TODO/LATER: ViewAspect must be passed from outside! 7132 sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT; 7133 7134 // JP 26.10.2001: Bug 93374 / 91928 the writer 7135 // objects need the correct visarea needs the 7136 // correct visarea, but this is not true for 7137 // PowerPoint (see bugdoc 94908b) 7138 // SJ: 19.11.2001 bug 94908, also chart objects 7139 // needs the correct visarea 7140 7141 // If pName is set this is an own embedded object, it should have the correct size internally 7142 // TODO/LATER: it might make sence in future to set the size stored in internal object 7143 if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) ) 7144 { 7145 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) ); 7146 Size aSz; 7147 if ( rVisArea.IsEmpty() ) 7148 aSz = lcl_GetPrefSize(rGrf, aMapMode ); 7149 else 7150 { 7151 aSz = rVisArea.GetSize(); 7152 aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode ); 7153 } 7154 7155 // don't modify the object 7156 //TODO/LATER: remove those hacks, that needs to be done differently! 7157 //xIPObj->EnableSetModified( sal_False ); 7158 awt::Size aSize; 7159 aSize.Width = aSz.Width(); 7160 aSize.Height = aSz.Height(); 7161 xObj->setVisualAreaSize( nViewAspect, aSize ); 7162 //xIPObj->EnableSetModified( sal_True ); 7163 } 7164 else if ( sStarName.EqualsAscii( "smath" ) ) 7165 { // SJ: force the object to recalc its visarea 7166 //TODO/LATER: wait for PrinterChangeNotification 7167 //xIPObj->OnDocumentPrinterChanged( NULL ); 7168 } 7169 } 7170 } 7171 7172 return xObj; 7173 } 7174 7175 // TODO/MBA: code review and testing! 7176 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage( 7177 const String& rStorageName, 7178 SotStorageRef& rSrcStorage, 7179 const uno::Reference < embed::XStorage >& xDestStorage, 7180 const Graphic& rGrf, 7181 const Rectangle& rBoundRect, 7182 const Rectangle& rVisArea, 7183 SvStream* pDataStrm, 7184 ErrCode& rError, 7185 sal_uInt32 nConvertFlags, 7186 sal_Int64 nReccomendedAspect ) 7187 { 7188 sal_Int64 nAspect = nReccomendedAspect; 7189 SdrOle2Obj* pRet = 0; 7190 if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() ) 7191 { 7192 comphelper::EmbeddedObjectContainer aCnt( xDestStorage ); 7193 // Ist der 01Ole-Stream ueberhaupt vorhanden ? 7194 // ( ist er z.B. bei FontWork nicht ) 7195 // Wenn nicht -> Einbindung als Grafik 7196 sal_Bool bValidStorage = sal_False; 7197 String aDstStgName( String::CreateFromAscii( 7198 RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj))); 7199 7200 aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr ); 7201 7202 { 7203 SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName, 7204 STREAM_READWRITE| STREAM_SHARE_DENYALL ); 7205 if( xObjStg.Is() ) 7206 { 7207 { 7208 sal_uInt8 aTestA[10]; // exist the \1CompObj-Stream ? 7209 SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream( 7210 String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"), 7211 RTL_TEXTENCODING_MS_1252 )); 7212 bValidStorage = xSrcTst.Is() && sizeof( aTestA ) == 7213 xSrcTst->Read( aTestA, sizeof( aTestA ) ); 7214 if( !bValidStorage ) 7215 { 7216 // or the \1Ole-Stream ? 7217 xSrcTst = xObjStg->OpenSotStream( 7218 String(RTL_CONSTASCII_STRINGPARAM("\1Ole"), 7219 RTL_TEXTENCODING_MS_1252 )); 7220 bValidStorage = xSrcTst.Is() && sizeof(aTestA) == 7221 xSrcTst->Read(aTestA, sizeof(aTestA)); 7222 } 7223 } 7224 7225 if( bValidStorage ) 7226 { 7227 if ( nAspect != embed::Aspects::MSOLE_ICON ) 7228 { 7229 // check whether the object is iconified one 7230 // usually this information is already known, the only exception 7231 // is a kind of embedded objects in Word documents 7232 // TODO/LATER: should the caller be notified if the aspect changes in future? 7233 7234 SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream( 7235 String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ), 7236 STREAM_STD_READ | STREAM_NOCREATE ); 7237 if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() ) 7238 { 7239 sal_uInt8 nByte = 0; 7240 *xObjInfoSrc >> nByte; 7241 if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON ) 7242 nAspect = embed::Aspects::MSOLE_ICON; 7243 } 7244 } 7245 7246 uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj( 7247 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea )); 7248 if ( xObj.is() ) 7249 { 7250 svt::EmbeddedObjectRef aObj( xObj, nAspect ); 7251 7252 // TODO/LATER: need MediaType 7253 aObj.SetGraphic( rGrf, ::rtl::OUString() ); 7254 7255 // TODO/MBA: check setting of PersistName 7256 pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false); 7257 // we have the Object, don't create another 7258 bValidStorage = false; 7259 } 7260 } 7261 } 7262 } 7263 7264 if( bValidStorage ) 7265 { 7266 // object is not an own object 7267 SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE ); 7268 7269 if ( xObjStor.Is() ) 7270 { 7271 SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ ); 7272 xSrcStor->CopyTo( xObjStor ); 7273 7274 if( !xObjStor->GetError() ) 7275 xObjStor->Commit(); 7276 7277 if( xObjStor->GetError() ) 7278 { 7279 rError = xObjStor->GetError(); 7280 bValidStorage = sal_False; 7281 } 7282 else if( !xObjStor.Is() ) 7283 bValidStorage = sal_False; 7284 } 7285 } 7286 else if( pDataStrm ) 7287 { 7288 sal_uInt32 nLen, nDummy; 7289 *pDataStrm >> nLen >> nDummy; 7290 if( SVSTREAM_OK != pDataStrm->GetError() || 7291 // Id in BugDoc - exist there other Ids? 7292 // The ConvertToOle2 - does not check for consistent 7293 0x30008 != nDummy ) 7294 bValidStorage = sal_False; 7295 else 7296 { 7297 // or is it an OLE-1 Stream in the DataStream? 7298 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName ); 7299 //TODO/MBA: remove metafile conversion from ConvertToOle2 7300 //when is this code used?! 7301 GDIMetaFile aMtf; 7302 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor ); 7303 xObjStor->Commit(); 7304 } 7305 } 7306 7307 if( bValidStorage ) 7308 { 7309 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName ); 7310 if( xObj.is() ) 7311 { 7312 // the visual area must be retrieved from the metafile (object doesn't know it so far) 7313 7314 if ( nAspect != embed::Aspects::MSOLE_ICON ) 7315 { 7316 // working with visual area can switch the object to running state 7317 awt::Size aAwtSz; 7318 try 7319 { 7320 // the provided visual area should be used, if there is any 7321 if ( rVisArea.IsEmpty() ) 7322 { 7323 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ); 7324 Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit))); 7325 aAwtSz.Width = aSz.Width(); 7326 aAwtSz.Height = aSz.Height(); 7327 } 7328 else 7329 { 7330 aAwtSz.Width = rVisArea.GetWidth(); 7331 aAwtSz.Height = rVisArea.GetHeight(); 7332 } 7333 //xInplaceObj->EnableSetModified( sal_False ); 7334 xObj->setVisualAreaSize( nAspect, aAwtSz ); 7335 //xInplaceObj->EnableSetModified( sal_True );*/ 7336 } 7337 catch( uno::Exception& ) 7338 { 7339 OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" ); 7340 } 7341 } 7342 7343 svt::EmbeddedObjectRef aObj( xObj, nAspect ); 7344 7345 // TODO/LATER: need MediaType 7346 aObj.SetGraphic( rGrf, ::rtl::OUString() ); 7347 7348 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false); 7349 } 7350 } 7351 } 7352 7353 return pRet; 7354 } 7355 7356 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const 7357 { 7358 SdrObject* pRet = NULL; 7359 7360 if(120 >= sal_uInt16(eTyp)) 7361 { 7362 pRet = new SdrRectObj(); 7363 } 7364 7365 DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM"); 7366 7367 return pRet; 7368 } 7369 7370 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 7371 const String& rPropName, sal_Bool bTestPropertyAvailability ) 7372 { 7373 sal_Bool bRetValue = sal_True; 7374 if ( bTestPropertyAvailability ) 7375 { 7376 bRetValue = sal_False; 7377 try 7378 { 7379 uno::Reference< beans::XPropertySetInfo > 7380 aXPropSetInfo( rXPropSet->getPropertySetInfo() ); 7381 if ( aXPropSetInfo.is() ) 7382 bRetValue = aXPropSetInfo->hasPropertyByName( rPropName ); 7383 } 7384 catch( uno::Exception& ) 7385 { 7386 bRetValue = sal_False; 7387 } 7388 } 7389 if ( bRetValue ) 7390 { 7391 try 7392 { 7393 rXPropSet->setPropertyValue( rPropName, rAny ); 7394 bRetValue = sal_True; 7395 } 7396 catch( uno::Exception& ) 7397 { 7398 bRetValue = sal_False; 7399 } 7400 } 7401 return bRetValue; 7402 } 7403 7404 SvxMSDffImportRec::SvxMSDffImportRec() 7405 : pObj( 0 ), 7406 pWrapPolygon(0), 7407 pClientAnchorBuffer( 0 ), 7408 nClientAnchorLen( 0 ), 7409 pClientDataBuffer( 0 ), 7410 nClientDataLen( 0 ), 7411 nXAlign( 0 ), // position n cm from left 7412 nXRelTo( 2 ), // relative to column 7413 nYAlign( 0 ), // position n cm below 7414 nYRelTo( 2 ), // relative to paragraph 7415 nLayoutInTableCell( 0 ), // element is laid out in table cell 7416 nTextRotationAngle( 0 ), 7417 nDxTextLeft( 144 ), 7418 nDyTextTop( 72 ), 7419 nDxTextRight( 144 ), 7420 nDyTextBottom( 72 ), 7421 nDxWrapDistLeft( 0 ), 7422 nDyWrapDistTop( 0 ), 7423 nDxWrapDistRight( 0 ), 7424 nDyWrapDistBottom(0 ), 7425 nCropFromTop( 0 ), 7426 nCropFromBottom( 0 ), 7427 nCropFromLeft( 0 ), 7428 nCropFromRight( 0 ), 7429 aTextId( 0, 0 ), 7430 nNextShapeId( 0 ), 7431 nShapeId( 0 ), 7432 eShapeType( mso_sptNil ) 7433 { 7434 eLineStyle = mso_lineSimple; // GPF-Bug #66227# 7435 bDrawHell = sal_False; 7436 bHidden = sal_False; 7437 // bInGroup = sal_False; 7438 bReplaceByFly = sal_False; 7439 bLastBoxInChain = sal_True; 7440 bHasUDefProp = sal_False; // was the DFF_msofbtUDefProp record set? 7441 bVFlip = sal_False; 7442 bHFlip = sal_False; 7443 bAutoWidth = sal_False; 7444 } 7445 7446 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy) 7447 : pObj( rCopy.pObj ), 7448 nXAlign( rCopy.nXAlign ), 7449 nXRelTo( rCopy.nXRelTo ), 7450 nYAlign( rCopy.nYAlign ), 7451 nYRelTo( rCopy.nYRelTo ), 7452 nLayoutInTableCell( rCopy.nLayoutInTableCell ), 7453 nTextRotationAngle( rCopy.nTextRotationAngle ), 7454 nDxTextLeft( rCopy.nDxTextLeft ), 7455 nDyTextTop( rCopy.nDyTextTop ), 7456 nDxTextRight( rCopy.nDxTextRight ), 7457 nDyTextBottom( rCopy.nDyTextBottom ), 7458 nDxWrapDistLeft( rCopy.nDxWrapDistLeft ), 7459 nDyWrapDistTop( rCopy.nDyWrapDistTop ), 7460 nDxWrapDistRight( rCopy.nDxWrapDistRight ), 7461 nDyWrapDistBottom(rCopy.nDyWrapDistBottom ), 7462 nCropFromTop( rCopy.nCropFromTop ), 7463 nCropFromBottom( rCopy.nCropFromBottom ), 7464 nCropFromLeft( rCopy.nCropFromLeft ), 7465 nCropFromRight( rCopy.nCropFromRight ), 7466 aTextId( rCopy.aTextId ), 7467 nNextShapeId( rCopy.nNextShapeId ), 7468 nShapeId( rCopy.nShapeId ), 7469 eShapeType( rCopy.eShapeType ) 7470 { 7471 eLineStyle = rCopy.eLineStyle; // GPF-Bug #66227# 7472 bDrawHell = rCopy.bDrawHell; 7473 bHidden = rCopy.bHidden; 7474 // bInGroup = rCopy.bInGroup; 7475 bReplaceByFly = rCopy.bReplaceByFly; 7476 bAutoWidth = rCopy.bAutoWidth; 7477 bLastBoxInChain = rCopy.bLastBoxInChain; 7478 bHasUDefProp = rCopy.bHasUDefProp; 7479 bVFlip = rCopy.bVFlip; 7480 bHFlip = rCopy.bHFlip; 7481 nClientAnchorLen = rCopy.nClientAnchorLen; 7482 if( rCopy.nClientAnchorLen ) 7483 { 7484 pClientAnchorBuffer = new char[ nClientAnchorLen ]; 7485 memcpy( pClientAnchorBuffer, 7486 rCopy.pClientAnchorBuffer, 7487 nClientAnchorLen ); 7488 } 7489 else 7490 pClientAnchorBuffer = 0; 7491 7492 nClientDataLen = rCopy.nClientDataLen; 7493 if( rCopy.nClientDataLen ) 7494 { 7495 pClientDataBuffer = new char[ nClientDataLen ]; 7496 memcpy( pClientDataBuffer, 7497 rCopy.pClientDataBuffer, 7498 nClientDataLen ); 7499 } 7500 else 7501 pClientDataBuffer = 0; 7502 7503 if (rCopy.pWrapPolygon) 7504 pWrapPolygon = new Polygon(*rCopy.pWrapPolygon); 7505 else 7506 pWrapPolygon = 0; 7507 } 7508 7509 SvxMSDffImportRec::~SvxMSDffImportRec() 7510 { 7511 if (pClientAnchorBuffer) 7512 delete[] pClientAnchorBuffer; 7513 if (pClientDataBuffer) 7514 delete[] pClientDataBuffer; 7515 if (pWrapPolygon) 7516 delete pWrapPolygon; 7517 } 7518 7519 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 7520 7521 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape ) 7522 { 7523 maShapeIdContainer[nShapeId] = pShape; 7524 } 7525 7526 void SvxMSDffManager::removeShapeId( SdrObject* pShape ) 7527 { 7528 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() ); 7529 const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() ); 7530 while( aIter != aEnd ) 7531 { 7532 if( (*aIter).second == pShape ) 7533 { 7534 maShapeIdContainer.erase( aIter ); 7535 break; 7536 } 7537 aIter++; 7538 } 7539 } 7540 7541 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId ) 7542 { 7543 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) ); 7544 return aIter != maShapeIdContainer.end() ? (*aIter).second : 0; 7545 } 7546