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