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 ) 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 if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) ) 4504 { 4505 sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength(); 4506 XPolygon aXP( (sal_uInt16)nNumElemVert ); 4507 // const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray(); 4508 for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ ) 4509 { 4510 Point aP; 4511 sal_Int32 nX = 0, nY = 0; 4512 seqCoordinates[ nPtNum ].First.Value >>= nX; 4513 seqCoordinates[ nPtNum ].Second.Value >>= nY; 4514 aP.X() = nX; 4515 aP.Y() = nY; 4516 aXP[ (sal_uInt16)nPtNum ] = aP; 4517 } 4518 aPolyBoundRect = Rectangle( aXP.GetBoundRect() ); 4519 } 4520 else 4521 aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 ); // defaulting 4522 4523 // clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry 4524 aGeometryItem.ClearPropertyValue( sHandles ); 4525 aGeometryItem.ClearPropertyValue( sEquations ); 4526 aGeometryItem.ClearPropertyValue( sViewBox ); 4527 aGeometryItem.ClearPropertyValue( sPath ); 4528 4529 sal_Int32 nEndAngle = 9000; 4530 sal_Int32 nStartAngle = 0; 4531 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues ); 4532 if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 ) 4533 { 4534 double fNumber; 4535 if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE ) 4536 { 4537 seqAdjustmentValues[ 0 ].Value >>= fNumber; 4538 nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 ); 4539 } 4540 else 4541 { 4542 fNumber = 270.0; 4543 seqAdjustmentValues[ 0 ].Value <<= fNumber; 4544 seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // so this value will properly be stored 4545 } 4546 4547 if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE ) 4548 { 4549 seqAdjustmentValues[ 1 ].Value >>= fNumber; 4550 nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 ); 4551 } 4552 else 4553 { 4554 fNumber = 0.0; 4555 seqAdjustmentValues[ 1 ].Value <<= fNumber; 4556 seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; 4557 } 4558 4559 PropertyValue aPropVal; 4560 aPropVal.Name = sAdjustmentValues; 4561 aPropVal.Value <<= seqAdjustmentValues; 4562 aGeometryItem.SetPropertyValue( aPropVal ); // storing the angle attribute 4563 } 4564 if ( nStartAngle != nEndAngle ) 4565 { 4566 XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2, 4567 (sal_uInt16)nStartAngle / 10, (sal_uInt16)nEndAngle / 10, sal_True ); 4568 Rectangle aPolyPieRect( aXPoly.GetBoundRect() ); 4569 4570 double fYScale, fXScale; 4571 double fYOfs, fXOfs; 4572 4573 Point aP( aObjData.aBoundRect.Center() ); 4574 Size aS( aObjData.aBoundRect.GetSize() ); 4575 aP.X() -= aS.Width() / 2; 4576 aP.Y() -= aS.Height() / 2; 4577 Rectangle aLogicRect( aP, aS ); 4578 4579 fYOfs = fXOfs = 0.0; 4580 4581 if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() ) 4582 { 4583 fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth(); 4584 if ( nSpFlags & SP_FFLIPH ) 4585 fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale; 4586 else 4587 fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale; 4588 } 4589 if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() ) 4590 { 4591 fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight(); 4592 if ( nSpFlags & SP_FFLIPV ) 4593 fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale; 4594 else 4595 fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale; 4596 } 4597 4598 fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth(); 4599 fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight(); 4600 4601 Rectangle aOldBoundRect( aObjData.aBoundRect ); 4602 aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ), 4603 Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) ); 4604 4605 // creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system 4606 double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth(); 4607 double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight(); 4608 sal_Int32 nLeft = (sal_Int32)(( aPolyPieRect.Left() - aPolyBoundRect.Left() ) * fTextFrameScaleX ); 4609 sal_Int32 nTop = (sal_Int32)(( aPolyPieRect.Top() - aPolyBoundRect.Top() ) * fTextFrameScaleY ); 4610 sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX ); 4611 sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() ) * fTextFrameScaleY ); 4612 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 ); 4613 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First, nLeft ); 4614 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second, nTop ); 4615 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight ); 4616 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom ); 4617 PropertyValue aProp; 4618 aProp.Name = sTextFrames; 4619 aProp.Value <<= aTextFrame; 4620 aGeometryItem.SetPropertyValue( sPath, aProp ); 4621 4622 // sj: taking care of the different rotation points, since the new arc is having a bigger snaprect 4623 if ( mnFix16Angle ) 4624 { 4625 sal_Int32 nAngle = mnFix16Angle; 4626 if ( nSpFlags & SP_FFLIPH ) 4627 nAngle = 36000 - nAngle; 4628 if ( nSpFlags & SP_FFLIPV ) 4629 nAngle = -nAngle; 4630 double a = nAngle * F_PI18000; 4631 double ss = sin( a ); 4632 double cc = cos( a ); 4633 Point aP1( aOldBoundRect.TopLeft() ); 4634 Point aC1( aObjData.aBoundRect.Center() ); 4635 Point aP2( aOldBoundRect.TopLeft() ); 4636 Point aC2( aOldBoundRect.Center() ); 4637 RotatePoint( aP1, aC1, ss, cc ); 4638 RotatePoint( aP2, aC2, ss, cc ); 4639 aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() ); 4640 } 4641 } 4642 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem ); 4643 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes(); 4644 4645 // now setting a new name, so the above correction is only done once when importing from ms 4646 SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ); 4647 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) ); 4648 const rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) ); 4649 PropertyValue aPropVal; 4650 aPropVal.Name = sType; 4651 aPropVal.Value <<= sName; 4652 aGeoName.SetPropertyValue( aPropVal ); 4653 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName ); 4654 } 4655 else 4656 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes(); 4657 4658 pRet->SetSnapRect( aObjData.aBoundRect ); 4659 EnhancedCustomShape2d aCustomShape2d( pRet ); 4660 aTextRect = aCustomShape2d.GetTextRect(); 4661 4662 bIsCustomShape = sal_True; 4663 4664 if( bIsConnector ) 4665 { 4666 if( nObjectRotation ) 4667 { 4668 double a = nObjectRotation * nPi180; 4669 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) ); 4670 } 4671 // Horizontal gespiegelt? 4672 if ( nSpFlags & SP_FFLIPH ) 4673 { 4674 Rectangle aBndRect( pRet->GetSnapRect() ); 4675 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() ); 4676 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4677 pRet->NbcMirror( aTop, aBottom ); 4678 } 4679 // Vertikal gespiegelt? 4680 if ( nSpFlags & SP_FFLIPV ) 4681 { 4682 Rectangle aBndRect( pRet->GetSnapRect() ); 4683 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 ); 4684 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4685 pRet->NbcMirror( aLeft, aRight ); 4686 } 4687 basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) ); 4688 SdrObject::Free( pRet ); 4689 4690 pRet = new SdrEdgeObj(); 4691 ApplyAttributes( rSt, aSet, aObjData ); 4692 pRet->SetLogicRect( aObjData.aBoundRect ); 4693 pRet->SetMergedItemSet(aSet); 4694 4695 // Konnektoren 4696 MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight ); 4697 4698 ((SdrEdgeObj*)pRet)->ConnectToNode(sal_True, NULL); 4699 ((SdrEdgeObj*)pRet)->ConnectToNode(sal_False, NULL); 4700 4701 Point aPoint1( aObjData.aBoundRect.TopLeft() ); 4702 Point aPoint2( aObjData.aBoundRect.BottomRight() ); 4703 4704 // Rotationen beachten 4705 if ( nObjectRotation ) 4706 { 4707 double a = nObjectRotation * nPi180; 4708 Point aCenter( aObjData.aBoundRect.Center() ); 4709 double ss = sin(a); 4710 double cc = cos(a); 4711 4712 RotatePoint(aPoint1, aCenter, ss, cc); 4713 RotatePoint(aPoint2, aCenter, ss, cc); 4714 } 4715 4716 // Linie innerhalb des Bereiches zurechtdrehen/spiegeln 4717 if ( nSpFlags & SP_FFLIPH ) 4718 { 4719 sal_Int32 n = aPoint1.X(); 4720 aPoint1.X() = aPoint2.X(); 4721 aPoint2.X() = n; 4722 } 4723 if ( nSpFlags & SP_FFLIPV ) 4724 { 4725 sal_Int32 n = aPoint1.Y(); 4726 aPoint1.Y() = aPoint2.Y(); 4727 aPoint2.Y() = n; 4728 } 4729 nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH ); 4730 4731 pRet->NbcSetPoint(aPoint1, 0L); // Startpunkt 4732 pRet->NbcSetPoint(aPoint2, 1L); // Endpunkt 4733 4734 sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist; 4735 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0; 4736 switch( eConnectorStyle ) 4737 { 4738 case mso_cxstyleBent: 4739 { 4740 aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) ); 4741 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630; 4742 } 4743 break; 4744 case mso_cxstyleCurved: 4745 aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) ); 4746 break; 4747 default: // mso_cxstyleStraight || mso_cxstyleNone 4748 aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) ); 4749 break; 4750 } 4751 aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) ); 4752 aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) ); 4753 aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) ); 4754 aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) ); 4755 4756 ((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly ); 4757 pRet->SetMergedItemSet( aSet ); 4758 } 4759 } 4760 } 4761 4762 if ( pRet ) 4763 { 4764 if( nObjectRotation ) 4765 { 4766 double a = nObjectRotation * nPi180; 4767 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) ); 4768 } 4769 // Horizontal gespiegelt? 4770 if ( nSpFlags & SP_FFLIPH ) 4771 { 4772 Rectangle aBndRect( pRet->GetSnapRect() ); 4773 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() ); 4774 Point aBottom( aTop.X(), aTop.Y() + 1000 ); 4775 pRet->NbcMirror( aTop, aBottom ); 4776 } 4777 // Vertikal gespiegelt? 4778 if ( nSpFlags & SP_FFLIPV ) 4779 { 4780 Rectangle aBndRect( pRet->GetSnapRect() ); 4781 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 ); 4782 Point aRight( aLeft.X() + 1000, aLeft.Y() ); 4783 pRet->NbcMirror( aLeft, aRight ); 4784 } 4785 } 4786 } 4787 } 4788 4789 // #i51348# #118052# name of the shape 4790 if( pRet ) 4791 { 4792 ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt ); 4793 if( aObjName.getLength() > 0 ) 4794 pRet->SetName( aObjName ); 4795 } 4796 4797 pRet = 4798 ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet); 4799 4800 if ( pRet ) 4801 { 4802 sal_Int32 nGroupProperties( GetPropertyValue( DFF_Prop_fPrint ) ); 4803 pRet->SetVisible( ( nGroupProperties & 2 ) == 0 ); 4804 pRet->SetPrintable( ( nGroupProperties & 1 ) != 0 ); 4805 } 4806 4807 if ( mbTracing ) 4808 mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP 4809 ? rtl::OUString::createFromAscii( "GroupShape" ) 4810 : rtl::OUString::createFromAscii( "Shape" ) ); 4811 //Import alt text as description 4812 if ( pRet && SeekToContent( DFF_Prop_wzDescription, rSt ) ) 4813 { 4814 String aAltText; 4815 MSDFFReadZString( rSt, aAltText, GetPropertyValue( DFF_Prop_wzDescription ), sal_True ); 4816 pRet->SetDescription( aAltText ); 4817 } 4818 4819 return pRet; 4820 } 4821 4822 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect ) 4823 { 4824 Rectangle aChildAnchor; 4825 rHd.SeekToContent( rSt ); 4826 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4827 { 4828 DffRecordHeader aShapeHd; 4829 rSt >> aShapeHd; 4830 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || 4831 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) 4832 { 4833 DffRecordHeader aShapeHd2( aShapeHd ); 4834 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) 4835 rSt >> aShapeHd2; 4836 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) ) 4837 { 4838 DffRecordHeader aShapeAtom; 4839 rSt >> aShapeAtom; 4840 4841 if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor ) 4842 { 4843 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT ) 4844 { 4845 sal_Int32 l, t, r, b; 4846 if ( aShapeAtom.nRecLen == 16 ) 4847 { 4848 rSt >> l >> t >> r >> b; 4849 } 4850 else 4851 { 4852 sal_Int16 ls, ts, rs, bs; 4853 rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ... 4854 l = ls, t = ts, r = rs, b = bs; 4855 } 4856 Scale( l ); 4857 Scale( t ); 4858 Scale( r ); 4859 Scale( b ); 4860 aClientRect = Rectangle( l, t, r, b ); 4861 } 4862 break; 4863 } 4864 else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor ) 4865 { 4866 sal_Int32 l, o, r, u; 4867 rSt >> l >> o >> r >> u; 4868 Scale( l ); 4869 Scale( o ); 4870 Scale( r ); 4871 Scale( u ); 4872 Rectangle aChild( l, o, r, u ); 4873 aChildAnchor.Union( aChild ); 4874 break; 4875 } 4876 aShapeAtom.SeekToEndOfRecord( rSt ); 4877 } 4878 } 4879 aShapeHd.SeekToEndOfRecord( rSt ); 4880 } 4881 return aChildAnchor; 4882 } 4883 4884 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt, 4885 Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor, 4886 const Rectangle& rClientRect, const Rectangle& rGlobalChildRect ) 4887 { 4888 sal_Bool bFirst = sal_True; 4889 rHd.SeekToContent( rSt ); 4890 DffRecordHeader aShapeHd; 4891 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) ) 4892 { 4893 rSt >> aShapeHd; 4894 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || 4895 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) 4896 { 4897 DffRecordHeader aShapeHd2( aShapeHd ); 4898 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) 4899 rSt >> aShapeHd2; 4900 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) ) 4901 { 4902 DffRecordHeader aShapeAtom; 4903 rSt >> aShapeAtom; 4904 if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor ) 4905 { 4906 sal_Int32 l, o, r, u; 4907 rSt >> l >> o >> r >> u; 4908 Scale( l ); 4909 Scale( o ); 4910 Scale( r ); 4911 Scale( u ); 4912 Rectangle aChild( l, o, r, u ); 4913 4914 if ( bFirst ) 4915 { 4916 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() ) 4917 { 4918 double fl = l; 4919 double fo = o; 4920 double fWidth = r - l; 4921 double fHeight= u - o; 4922 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth(); 4923 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight(); 4924 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left(); 4925 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top(); 4926 fWidth *= fXScale; 4927 fHeight *= fYScale; 4928 rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) ); 4929 } 4930 bFirst = sal_False; 4931 } 4932 else 4933 rGroupChildAnchor.Union( aChild ); 4934 break; 4935 } 4936 aShapeAtom.SeekToEndOfRecord( rSt ); 4937 } 4938 } 4939 aShapeHd.SeekToEndOfRecord( rSt ); 4940 } 4941 } 4942 4943 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt, 4944 DffObjData& rObjData, 4945 void* pData, 4946 Rectangle& rTextRect, 4947 SdrObject* pObj 4948 ) 4949 { 4950 if( !rTextRect.IsEmpty() ) 4951 { 4952 SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData; 4953 SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec; 4954 SvxMSDffImportRec* pTextImpRec = pImpRec; 4955 4956 // fill Import Record with data 4957 pImpRec->nShapeId = rObjData.nShapeId; 4958 pImpRec->eShapeType = rObjData.eShapeType; 4959 4960 MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue( 4961 DFF_Prop_WrapText, 4962 mso_wrapSquare ) ); 4963 rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, 4964 DFF_msofbtClientAnchor, 4965 SEEK_FROM_CURRENT_AND_RESTART ); 4966 if( rObjData.bClientAnchor ) 4967 ProcessClientAnchor( rSt, 4968 maShapeRecords.Current()->nRecLen, 4969 pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen ); 4970 4971 rObjData.bClientData = maShapeRecords.SeekToContent( rSt, 4972 DFF_msofbtClientData, 4973 SEEK_FROM_CURRENT_AND_RESTART ); 4974 if( rObjData.bClientData ) 4975 ProcessClientData( rSt, 4976 maShapeRecords.Current()->nRecLen, 4977 pImpRec->pClientDataBuffer, pImpRec->nClientDataLen ); 4978 4979 4980 // process user (== Winword) defined parameters in 0xF122 record 4981 if( maShapeRecords.SeekToContent( rSt, 4982 DFF_msofbtUDefProp, 4983 SEEK_FROM_CURRENT_AND_RESTART ) 4984 && maShapeRecords.Current()->nRecLen ) 4985 { 4986 sal_uInt32 nBytesLeft = maShapeRecords.Current()->nRecLen; 4987 sal_uInt32 nUDData; 4988 sal_uInt16 nPID; 4989 while( 5 < nBytesLeft ) 4990 { 4991 rSt >> nPID; 4992 if ( rSt.GetError() != 0 ) 4993 break; 4994 rSt >> nUDData; 4995 switch( nPID ) 4996 { 4997 case 0x038F: pImpRec->nXAlign = nUDData; break; 4998 case 0x0390: pImpRec->nXRelTo = nUDData; break; 4999 case 0x0391: pImpRec->nYAlign = nUDData; break; 5000 case 0x0392: pImpRec->nYRelTo = nUDData; break; 5001 case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break; 5002 } 5003 if ( rSt.GetError() != 0 ) 5004 break; 5005 pImpRec->bHasUDefProp = sal_True; 5006 nBytesLeft -= 6; 5007 } 5008 } 5009 5010 // Textrahmen, auch Title oder Outline 5011 SdrObject* pOrgObj = pObj; 5012 SdrRectObj* pTextObj = 0; 5013 sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 ); 5014 if( nTextId ) 5015 { 5016 SfxItemSet aSet( pSdrModel->GetItemPool() ); 5017 5018 //Originally anything that as a mso_sptTextBox was created as a 5019 //textbox, this was changed for #88277# to be created as a simple 5020 //rect to keep impress happy. For the rest of us we'd like to turn 5021 //it back into a textbox again. 5022 FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox); 5023 if (!bTextFrame) 5024 { 5025 //Either 5026 //a) its a simple text object or 5027 //b) its a rectangle with text and square wrapping. 5028 bTextFrame = 5029 ( 5030 (pImpRec->eShapeType == mso_sptTextSimple) || 5031 ( 5032 (pImpRec->eShapeType == mso_sptRectangle) 5033 && (eWrapMode == mso_wrapSquare) 5034 && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() ) 5035 ) 5036 ); 5037 } 5038 5039 if (bTextFrame) 5040 { 5041 SdrObject::Free( pObj ); 5042 pObj = pOrgObj = 0; 5043 } 5044 5045 // Distance of Textbox to it's surrounding Customshape 5046 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L); 5047 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L ); 5048 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L ); 5049 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L ); 5050 5051 ScaleEmu( nTextLeft ); 5052 ScaleEmu( nTextRight ); 5053 ScaleEmu( nTextTop ); 5054 ScaleEmu( nTextBottom ); 5055 5056 sal_Int32 nTextRotationAngle=0; 5057 bool bVerticalText = false; 5058 if ( IsProperty( DFF_Prop_txflTextFlow ) ) 5059 { 5060 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue( 5061 DFF_Prop_txflTextFlow) & 0xFFFF); 5062 switch( eTextFlow ) 5063 { 5064 case mso_txflBtoT: 5065 nTextRotationAngle = 9000; 5066 break; 5067 case mso_txflVertN: 5068 case mso_txflTtoBN: 5069 nTextRotationAngle = 27000; 5070 break; 5071 case mso_txflTtoBA: 5072 bVerticalText = true; 5073 break; 5074 case mso_txflHorzA: 5075 bVerticalText = true; 5076 nTextRotationAngle = 9000; 5077 case mso_txflHorzN: 5078 default : 5079 break; 5080 } 5081 } 5082 5083 if (nTextRotationAngle) 5084 { 5085 while (nTextRotationAngle > 360000) 5086 nTextRotationAngle-=9000; 5087 switch (nTextRotationAngle) 5088 { 5089 case 9000: 5090 { 5091 long nWidth = rTextRect.GetWidth(); 5092 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight(); 5093 rTextRect.Bottom() = rTextRect.Top() + nWidth; 5094 5095 sal_Int32 nOldTextLeft = nTextLeft; 5096 sal_Int32 nOldTextRight = nTextRight; 5097 sal_Int32 nOldTextTop = nTextTop; 5098 sal_Int32 nOldTextBottom = nTextBottom; 5099 5100 nTextLeft = nOldTextBottom; 5101 nTextRight = nOldTextTop; 5102 nTextTop = nOldTextLeft; 5103 nTextBottom = nOldTextRight; 5104 } 5105 break; 5106 case 27000: 5107 { 5108 long nWidth = rTextRect.GetWidth(); 5109 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight(); 5110 rTextRect.Bottom() = rTextRect.Top() + nWidth; 5111 5112 sal_Int32 nOldTextLeft = nTextLeft; 5113 sal_Int32 nOldTextRight = nTextRight; 5114 sal_Int32 nOldTextTop = nTextTop; 5115 sal_Int32 nOldTextBottom = nTextBottom; 5116 5117 nTextLeft = nOldTextTop; 5118 nTextRight = nOldTextBottom; 5119 nTextTop = nOldTextRight; 5120 nTextBottom = nOldTextLeft; 5121 } 5122 break; 5123 default: 5124 break; 5125 } 5126 } 5127 5128 pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect); 5129 pTextImpRec = new SvxMSDffImportRec(*pImpRec); 5130 5131 // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin, 5132 // hier rausrechnen 5133 Rectangle aNewRect(rTextRect); 5134 aNewRect.Bottom() -= nTextTop + nTextBottom; 5135 aNewRect.Right() -= nTextLeft + nTextRight; 5136 5137 // Nur falls es eine einfache Textbox ist, darf der Writer 5138 // das Objekt durch einen Rahmen ersetzen, ansonsten 5139 if( bTextFrame ) 5140 { 5141 SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId ); 5142 aTmpRec.bSortByShapeId = sal_True; 5143 5144 sal_uInt16 nFound; 5145 if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) ) 5146 { 5147 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound); 5148 pTextImpRec->bReplaceByFly = rInfo.bReplaceByFly; 5149 pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain; 5150 } 5151 } 5152 5153 if( !pObj ) 5154 ApplyAttributes( rSt, aSet, rObjData ); 5155 5156 bool bFitText = false; 5157 if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2) 5158 { 5159 aSet.Put( SdrTextAutoGrowHeightItem( sal_True ) ); 5160 aSet.Put( SdrTextMinFrameHeightItem( 5161 aNewRect.Bottom() - aNewRect.Top() ) ); 5162 aSet.Put( SdrTextMinFrameWidthItem( 5163 aNewRect.Right() - aNewRect.Left() ) ); 5164 bFitText = true; 5165 } 5166 else 5167 { 5168 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) ); 5169 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) ); 5170 } 5171 5172 switch ( (MSO_WrapMode) 5173 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) ) 5174 { 5175 case mso_wrapNone : 5176 aSet.Put( SdrTextAutoGrowWidthItem( sal_True ) ); 5177 if (bFitText) 5178 { 5179 //can't do autowidth in flys #i107184# 5180 pTextImpRec->bReplaceByFly = false; 5181 } 5182 break; 5183 case mso_wrapByPoints : 5184 aSet.Put( SdrTextContourFrameItem( sal_True ) ); 5185 break; 5186 default: break; 5187 } 5188 5189 // Abstaende an den Raendern der Textbox setzen 5190 aSet.Put( SdrTextLeftDistItem( nTextLeft ) ); 5191 aSet.Put( SdrTextRightDistItem( nTextRight ) ); 5192 aSet.Put( SdrTextUpperDistItem( nTextTop ) ); 5193 aSet.Put( SdrTextLowerDistItem( nTextBottom ) ); 5194 pTextImpRec->nDxTextLeft = nTextLeft; 5195 pTextImpRec->nDyTextTop = nTextTop; 5196 pTextImpRec->nDxTextRight = nTextRight; 5197 pTextImpRec->nDyTextBottom = nTextBottom; 5198 5199 // Textverankerung lesen 5200 if ( IsProperty( DFF_Prop_anchorText ) ) 5201 { 5202 MSO_Anchor eTextAnchor = 5203 (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText ); 5204 5205 SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER; 5206 sal_Bool bTVASet(sal_False); 5207 SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER; 5208 sal_Bool bTHASet(sal_False); 5209 5210 switch( eTextAnchor ) 5211 { 5212 case mso_anchorTop: 5213 { 5214 eTVA = SDRTEXTVERTADJUST_TOP; 5215 bTVASet = sal_True; 5216 } 5217 break; 5218 case mso_anchorTopCentered: 5219 { 5220 eTVA = SDRTEXTVERTADJUST_TOP; 5221 bTVASet = sal_True; 5222 bTHASet = sal_True; 5223 } 5224 break; 5225 5226 case mso_anchorMiddle: 5227 bTVASet = sal_True; 5228 break; 5229 case mso_anchorMiddleCentered: 5230 { 5231 bTVASet = sal_True; 5232 bTHASet = sal_True; 5233 } 5234 break; 5235 case mso_anchorBottom: 5236 { 5237 eTVA = SDRTEXTVERTADJUST_BOTTOM; 5238 bTVASet = sal_True; 5239 } 5240 break; 5241 case mso_anchorBottomCentered: 5242 { 5243 eTVA = SDRTEXTVERTADJUST_BOTTOM; 5244 bTVASet = sal_True; 5245 bTHASet = sal_True; 5246 } 5247 break; 5248 /* 5249 case mso_anchorTopBaseline: 5250 case mso_anchorBottomBaseline: 5251 case mso_anchorTopCenteredBaseline: 5252 case mso_anchorBottomCenteredBaseline: 5253 break; 5254 */ 5255 default : break; 5256 } 5257 // Einsetzen 5258 if ( bTVASet ) 5259 aSet.Put( SdrTextVertAdjustItem( eTVA ) ); 5260 if ( bTHASet ) 5261 aSet.Put( SdrTextHorzAdjustItem( eTHA ) ); 5262 } 5263 5264 pTextObj->SetMergedItemSet(aSet); 5265 pTextObj->SetModel(pSdrModel); 5266 5267 if (bVerticalText) 5268 pTextObj->SetVerticalWriting(sal_True); 5269 5270 if (nTextRotationAngle) 5271 { 5272 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ? 5273 rTextRect.GetWidth() : rTextRect.GetHeight(); 5274 nMinWH /= 2; 5275 Point aPivot(rTextRect.TopLeft()); 5276 aPivot.X() += nMinWH; 5277 aPivot.Y() += nMinWH; 5278 double a = nTextRotationAngle * nPi180; 5279 pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a)); 5280 } 5281 5282 // rotate text with shape ? 5283 if ( mnFix16Angle ) 5284 { 5285 double a = mnFix16Angle * nPi180; 5286 pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle, 5287 sin( a ), cos( a ) ); 5288 } 5289 5290 if( !pObj ) 5291 { 5292 pObj = pTextObj; 5293 } 5294 else 5295 { 5296 if( pTextObj != pObj ) 5297 { 5298 SdrObject* pGroup = new SdrObjGroup; 5299 pGroup->GetSubList()->NbcInsertObject( pObj ); 5300 pGroup->GetSubList()->NbcInsertObject( pTextObj ); 5301 if (pOrgObj == pObj) 5302 pOrgObj = pGroup; 5303 else 5304 pOrgObj = pObj; 5305 pObj = pGroup; 5306 } 5307 } 5308 } 5309 else if( !pObj ) 5310 { 5311 // simple rectangular objects are ignored by ImportObj() :-( 5312 // this is OK for Draw but not for Calc and Writer 5313 // cause here these objects have a default border 5314 pObj = new SdrRectObj(rTextRect); 5315 pOrgObj = pObj; 5316 pObj->SetModel( pSdrModel ); 5317 SfxItemSet aSet( pSdrModel->GetItemPool() ); 5318 ApplyAttributes( rSt, aSet, rObjData ); 5319 5320 const SfxPoolItem* pPoolItem=NULL; 5321 SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR, 5322 sal_False, &pPoolItem ); 5323 if( SFX_ITEM_DEFAULT == eState ) 5324 aSet.Put( XFillColorItem( String(), 5325 Color( mnDefaultColor ) ) ); 5326 pObj->SetMergedItemSet(aSet); 5327 } 5328 5329 //Means that fBehindDocument is set 5330 if (GetPropertyValue(DFF_Prop_fPrint) & 0x20) 5331 pImpRec->bDrawHell = sal_True; 5332 else 5333 pImpRec->bDrawHell = sal_False; 5334 if (GetPropertyValue(DFF_Prop_fPrint) & 0x02) 5335 pImpRec->bHidden = sal_True; 5336 pTextImpRec->bDrawHell = pImpRec->bDrawHell; 5337 pTextImpRec->bHidden = pImpRec->bHidden; 5338 pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 ); 5339 pTextImpRec->nNextShapeId=pImpRec->nNextShapeId; 5340 5341 if ( nTextId ) 5342 { 5343 pTextImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 ); 5344 pTextImpRec->aTextId.nSequence = (sal_uInt16)nTextId; 5345 } 5346 5347 pTextImpRec->nDxWrapDistLeft = GetPropertyValue( 5348 DFF_Prop_dxWrapDistLeft, 114935L ) / 635L; 5349 pTextImpRec->nDyWrapDistTop = GetPropertyValue( 5350 DFF_Prop_dyWrapDistTop, 0 ) / 635L; 5351 pTextImpRec->nDxWrapDistRight = GetPropertyValue( 5352 DFF_Prop_dxWrapDistRight, 114935L ) / 635L; 5353 pTextImpRec->nDyWrapDistBottom = GetPropertyValue( 5354 DFF_Prop_dyWrapDistBottom, 0 ) / 635L; 5355 // 16.16 fraction times total image width or height, as appropriate. 5356 5357 if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt)) 5358 { 5359 delete pTextImpRec->pWrapPolygon; 5360 sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert; 5361 rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert; 5362 if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4))) 5363 { 5364 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert); 5365 for (sal_uInt16 i = 0; i < nNumElemVert; ++i) 5366 { 5367 sal_Int32 nX, nY; 5368 if (nElemSizeVert == 8) 5369 rSt >> nX >> nY; 5370 else 5371 { 5372 sal_Int16 nSmallX, nSmallY; 5373 rSt >> nSmallX >> nSmallY; 5374 nX = nSmallX; 5375 nY = nSmallY; 5376 } 5377 (*(pTextImpRec->pWrapPolygon))[i].X() = nX; 5378 (*(pTextImpRec->pWrapPolygon))[i].Y() = nY; 5379 } 5380 } 5381 } 5382 5383 pImpRec->nCropFromTop = GetPropertyValue( 5384 DFF_Prop_cropFromTop, 0 ); 5385 pImpRec->nCropFromBottom = GetPropertyValue( 5386 DFF_Prop_cropFromBottom, 0 ); 5387 pImpRec->nCropFromLeft = GetPropertyValue( 5388 DFF_Prop_cropFromLeft, 0 ); 5389 pImpRec->nCropFromRight = GetPropertyValue( 5390 DFF_Prop_cropFromRight, 0 ); 5391 5392 pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false; 5393 pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false; 5394 5395 sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash ); 5396 pImpRec->eLineStyle = (nLineFlags & 8) 5397 ? (MSO_LineStyle)GetPropertyValue( 5398 DFF_Prop_lineStyle, 5399 mso_lineSimple ) 5400 : (MSO_LineStyle)USHRT_MAX; 5401 pTextImpRec->eLineStyle = pImpRec->eLineStyle; 5402 5403 if( pImpRec->nShapeId ) 5404 { 5405 // Import-Record-Liste ergaenzen 5406 if( pOrgObj ) 5407 { 5408 pImpRec->pObj = pOrgObj; 5409 rImportData.aRecords.Insert( pImpRec ); 5410 } 5411 5412 if( pTextObj && (pOrgObj != pTextObj) ) 5413 { 5414 // Modify ShapeId (must be unique) 5415 pImpRec->nShapeId |= 0x8000000; 5416 pTextImpRec->pObj = pTextObj; 5417 rImportData.aRecords.Insert( pTextImpRec ); 5418 } 5419 5420 // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen 5421 /*Only store objects which are not deep inside the tree*/ 5422 if( ( rObjData.nCalledByGroup == 0 ) 5423 || 5424 ( (rObjData.nSpFlags & SP_FGROUP) 5425 && (rObjData.nCalledByGroup < 2) ) 5426 ) 5427 StoreShapeOrder( pImpRec->nShapeId, 5428 ( ( (sal_uLong)pImpRec->aTextId.nTxBxS ) << 16 ) 5429 + pImpRec->aTextId.nSequence, pObj ); 5430 } 5431 else 5432 delete pImpRec; 5433 } 5434 5435 return pObj; 5436 }; 5437 5438 void SvxMSDffManager::StoreShapeOrder(sal_uLong nId, 5439 sal_uLong nTxBx, 5440 SdrObject* pObject, 5441 SwFlyFrmFmt* pFly, 5442 short nHdFtSection) const 5443 { 5444 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5445 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5446 { 5447 SvxMSDffShapeOrder& rOrder 5448 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5449 5450 if( rOrder.nShapeId == nId ) 5451 { 5452 rOrder.nTxBxComp = nTxBx; 5453 rOrder.pObj = pObject; 5454 rOrder.pFly = pFly; 5455 rOrder.nHdFtSection = nHdFtSection; 5456 } 5457 } 5458 } 5459 5460 5461 void SvxMSDffManager::ExchangeInShapeOrder( SdrObject* pOldObject, 5462 sal_uLong nTxBx, 5463 SwFlyFrmFmt* pFly, 5464 SdrObject* pObject) const 5465 { 5466 sal_uInt16 nShpCnt = pShapeOrders->Count(); 5467 for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++) 5468 { 5469 SvxMSDffShapeOrder& rOrder 5470 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum )); 5471 5472 if( rOrder.pObj == pOldObject ) 5473 { 5474 rOrder.pFly = pFly; 5475 rOrder.pObj = pObject; 5476 rOrder.nTxBxComp = nTxBx; 5477 } 5478 } 5479 } 5480 5481 5482 void SvxMSDffManager::RemoveFromShapeOrder( 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 == pObject ) 5491 { 5492 rOrder.pObj = 0; 5493 rOrder.pFly = 0; 5494 rOrder.nTxBxComp = 0; 5495 } 5496 } 5497 } 5498 5499 5500 5501 5502 //--------------------------------------------------------------------------- 5503 // Hilfs Deklarationen 5504 //--------------------------------------------------------------------------- 5505 5506 /*struct SvxMSDffBLIPInfo -> in's Header-File 5507 { 5508 sal_uInt16 nBLIPType; // Art des BLIP: z.B. 6 fuer PNG 5509 sal_uLong nFilePos; // Offset des BLIP im Daten-Stream 5510 sal_uLong nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt 5511 SvxMSDffBLIPInfo(sal_uInt16 nBType, sal_uLong nFPos, sal_uLong nBSize): 5512 nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){} 5513 }; 5514 */ 5515 5516 SV_IMPL_PTRARR( SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr ); 5517 5518 SV_IMPL_PTRARR( SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr ); 5519 5520 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr ); 5521 5522 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr ); 5523 5524 5525 // Liste aller SvxMSDffImportRec fuer eine Gruppe 5526 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr) 5527 5528 //--------------------------------------------------------------------------- 5529 // exportierte Klasse: oeffentliche Methoden 5530 //--------------------------------------------------------------------------- 5531 5532 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_, 5533 const String& rBaseURL, 5534 long nOffsDgg_, 5535 SvStream* pStData_, 5536 SdrModel* pSdrModel_,// s. unten: SetModel() 5537 long nApplicationScale, 5538 ColorData mnDefaultColor_, 5539 sal_uLong nDefaultFontHeight_, 5540 SvStream* pStData2_, 5541 MSFilterTracer* pTracer ) 5542 :DffPropertyReader( *this ), 5543 pFormModel( NULL ), 5544 pBLIPInfos( new SvxMSDffBLIPInfos ), 5545 pShapeInfos( new SvxMSDffShapeInfos ), 5546 pShapeOrders( new SvxMSDffShapeOrders ), 5547 nDefaultFontHeight( nDefaultFontHeight_), 5548 nOffsDgg( nOffsDgg_ ), 5549 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen, 5550 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt 5551 maBaseURL( rBaseURL ), 5552 mpFidcls( NULL ), 5553 rStCtrl( rStCtrl_ ), 5554 pStData( pStData_ ), 5555 pStData2( pStData2_ ), 5556 nSvxMSDffSettings( 0 ), 5557 nSvxMSDffOLEConvFlags( 0 ), 5558 pSecPropSet( NULL ), 5559 pEscherBlipCache( NULL ), 5560 mnDefaultColor( mnDefaultColor_), 5561 mpTracer( pTracer ), 5562 mbTracing( sal_False ) 5563 { 5564 if ( mpTracer ) 5565 { 5566 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) ); 5567 aAny >>= mbTracing; 5568 } 5569 SetModel( pSdrModel_, nApplicationScale ); 5570 5571 // FilePos des/der Stream(s) merken 5572 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 5573 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 5574 5575 // Falls kein Datenstream angegeben, gehen wir davon aus, 5576 // dass die BLIPs im Steuerstream stehen. 5577 if( !pStData ) 5578 pStData = &rStCtrl; 5579 5580 SetDefaultPropSet( rStCtrl, nOffsDgg ); 5581 5582 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen 5583 GetCtrlData( nOffsDgg ); 5584 5585 // Text-Box-Story-Ketten-Infos ueberpruefen 5586 CheckTxBxStoryChain(); 5587 5588 // alte FilePos des/der Stream(s) restaurieren 5589 rStCtrl.Seek( nOldPosCtrl ); 5590 if( &rStCtrl != pStData ) 5591 pStData->Seek( nOldPosData ); 5592 } 5593 5594 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer ) 5595 :DffPropertyReader( *this ), 5596 pFormModel( NULL ), 5597 pBLIPInfos( new SvxMSDffBLIPInfos ), 5598 pShapeInfos( new SvxMSDffShapeInfos ), 5599 pShapeOrders( new SvxMSDffShapeOrders ), 5600 nDefaultFontHeight( 24 ), 5601 nOffsDgg( 0 ), 5602 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen, 5603 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt 5604 maBaseURL( rBaseURL ), 5605 mpFidcls( NULL ), 5606 rStCtrl( rStCtrl_ ), 5607 pStData( 0 ), 5608 pStData2( 0 ), 5609 nSvxMSDffSettings( 0 ), 5610 nSvxMSDffOLEConvFlags( 0 ), 5611 pSecPropSet( NULL ), 5612 pEscherBlipCache( NULL ), 5613 mnDefaultColor( COL_DEFAULT ), 5614 mpTracer( pTracer ), 5615 mbTracing( sal_False ) 5616 { 5617 if ( mpTracer ) 5618 { 5619 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) ); 5620 aAny >>= mbTracing; 5621 } 5622 SetModel( NULL, 0 ); 5623 } 5624 5625 SvxMSDffManager::~SvxMSDffManager() 5626 { 5627 if ( pEscherBlipCache ) 5628 { 5629 void* pPtr; 5630 for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() ) 5631 delete (EscherBlipCacheEntry*)pPtr; 5632 delete pEscherBlipCache; 5633 } 5634 delete pSecPropSet; 5635 delete pBLIPInfos; 5636 delete pShapeInfos; 5637 delete pShapeOrders; 5638 delete pFormModel; 5639 delete[] mpFidcls; 5640 } 5641 5642 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags ) 5643 { 5644 nOffsDgg = nOffsDgg_; 5645 pStData = pStData_; 5646 nSvxMSDffOLEConvFlags = nOleConvFlags; 5647 5648 // FilePos des/der Stream(s) merken 5649 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 5650 5651 SetDefaultPropSet( rStCtrl, nOffsDgg ); 5652 5653 // insert fidcl cluster table 5654 GetFidclData( nOffsDgg ); 5655 5656 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen 5657 GetCtrlData( nOffsDgg ); 5658 5659 // Text-Box-Story-Ketten-Infos ueberpruefen 5660 CheckTxBxStoryChain(); 5661 5662 // alte FilePos des/der Stream(s) restaurieren 5663 rStCtrl.Seek( nOldPosCtrl ); 5664 } 5665 5666 void SvxMSDffManager::SetDgContainer( SvStream& rSt ) 5667 { 5668 sal_uInt32 nFilePos = rSt.Tell(); 5669 DffRecordHeader aDgContHd; 5670 rSt >> aDgContHd; 5671 // insert this container only if there is also a DgAtom 5672 if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) ) 5673 { 5674 DffRecordHeader aRecHd; 5675 rSt >> aRecHd; 5676 sal_uInt32 nDrawingId = aRecHd.nRecInstance; 5677 maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos ); 5678 rSt.Seek( nFilePos ); 5679 } 5680 } 5681 5682 void SvxMSDffManager::GetFidclData( long nOffsDggL ) 5683 { 5684 if ( nOffsDggL ) 5685 { 5686 sal_uInt32 nDummy, nMerk = rStCtrl.Tell(); 5687 rStCtrl.Seek( nOffsDggL ); 5688 5689 DffRecordHeader aRecHd; 5690 rStCtrl >> aRecHd; 5691 5692 DffRecordHeader aDggAtomHd; 5693 if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) ) 5694 { 5695 aDggAtomHd.SeekToContent( rStCtrl ); 5696 rStCtrl >> mnCurMaxShapeId 5697 >> mnIdClusters 5698 >> nDummy 5699 >> mnDrawingsSaved; 5700 5701 if ( mnIdClusters-- > 2 ) 5702 { 5703 if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) ) 5704 { 5705 //mpFidcls = new FIDCL[ mnIdClusters ]; 5706 mpFidcls = new (std::nothrow) FIDCL[ mnIdClusters ]; 5707 if ( mpFidcls ) { 5708 for ( sal_uInt32 i = 0; i < mnIdClusters; i++ ) 5709 { 5710 rStCtrl >> mpFidcls[ i ].dgid 5711 >> mpFidcls[ i ].cspidCur; 5712 } 5713 } 5714 } 5715 } 5716 } 5717 rStCtrl.Seek( nMerk ); 5718 } 5719 } 5720 5721 void SvxMSDffManager::CheckTxBxStoryChain() 5722 { 5723 SvxMSDffShapeInfos* pOld = pShapeInfos; 5724 sal_uInt16 nCnt = pOld->Count(); 5725 pShapeInfos = new SvxMSDffShapeInfos( (nCnt < 255) 5726 ? nCnt 5727 : 255 ); 5728 // altes Info-Array ueberarbeiten 5729 // (ist sortiert nach nTxBxComp) 5730 sal_uLong nChain = ULONG_MAX; 5731 sal_uInt16 nObjMark = 0; 5732 sal_Bool bSetReplaceFALSE = sal_False; 5733 sal_uInt16 nObj; 5734 for( nObj = 0; nObj < nCnt; ++nObj ) 5735 { 5736 SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj ); 5737 if( pObj->nTxBxComp ) 5738 { 5739 pObj->bLastBoxInChain = sal_False; 5740 // Gruppenwechsel ? 5741 // --> OD 2008-07-28 #156763# 5742 // the text id also contains an internal drawing container id 5743 // to distinguish between text id of drawing objects in different 5744 // drawing containers. 5745 // if( nChain != (pObj->nTxBxComp & 0xFFFF0000) ) 5746 if( nChain != pObj->nTxBxComp ) 5747 // <-- 5748 { 5749 // voriger war letzter seiner Gruppe 5750 if( nObj ) 5751 pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True; 5752 // Merker und Hilfs-Flag zuruecksetzen 5753 nObjMark = nObj; 5754 // --> OD 2008-07-28 #156763# 5755 // nChain = pObj->nTxBxComp & 0xFFFF0000; 5756 nChain = pObj->nTxBxComp; 5757 // <-- 5758 bSetReplaceFALSE = !pObj->bReplaceByFly; 5759 } 5760 else 5761 if( !pObj->bReplaceByFly ) 5762 { 5763 // Objekt, das NICHT durch Rahmen ersetzt werden darf ? 5764 // Hilfs-Flag setzen 5765 bSetReplaceFALSE = sal_True; 5766 // ggfs Flag in Anfang der Gruppe austragen 5767 for( sal_uInt16 nObj2 = nObjMark; nObj2 < nObj; ++nObj2 ) 5768 pOld->GetObject( nObj2 )->bReplaceByFly = sal_False; 5769 } 5770 5771 if( bSetReplaceFALSE ) 5772 { 5773 pObj->bReplaceByFly = sal_False; 5774 } 5775 } 5776 // alle Shape-Info-Objekte in pShapeInfos umkopieren 5777 // (aber nach nShapeId sortieren) 5778 pObj->bSortByShapeId = sal_True; 5779 // --> OD 2008-07-28 #156763# 5780 pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000; 5781 // <-- 5782 pShapeInfos->Insert( pObj ); 5783 } 5784 // voriger war letzter seiner Gruppe 5785 if( nObj ) 5786 pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True; 5787 // urspruengliches Array freigeben, ohne Objekte zu zerstoeren 5788 pOld->Remove((sal_uInt16)0, nCnt); 5789 delete pOld; 5790 } 5791 5792 5793 /***************************************************************************** 5794 5795 Einlesen der Shape-Infos im Ctor: 5796 --------------------------------- 5797 merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos 5798 ========= ============ ============= 5799 und merken des File-Offsets fuer jedes Blip 5800 ============ 5801 ******************************************************************************/ 5802 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ ) 5803 { 5804 // Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen 5805 long nOffsDggL = nOffsDgg_; 5806 5807 // Kontroll Stream positionieren 5808 rStCtrl.Seek( nOffsDggL ); 5809 5810 sal_uInt8 nVer; 5811 sal_uInt16 nInst; 5812 sal_uInt16 nFbt; 5813 sal_uInt32 nLength; 5814 if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return; 5815 5816 sal_Bool bOk; 5817 sal_uLong nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE; 5818 5819 // Fall A: erst Drawing Group Container, dann n Mal Drawing Container 5820 if( DFF_msofbtDggContainer == nFbt ) 5821 { 5822 GetDrawingGroupContainerData( rStCtrl, nLength ); 5823 5824 rStCtrl.Seek( STREAM_SEEK_TO_END ); 5825 sal_uInt32 nMaxStrPos = rStCtrl.Tell(); 5826 5827 nPos += nLength; 5828 // --> OD 2008-07-28 #156763# 5829 unsigned long nDrawingContainerId = 1; 5830 // <-- 5831 do 5832 { 5833 rStCtrl.Seek( nPos ); 5834 5835 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt ); 5836 5837 if( !bOk ) 5838 { 5839 nPos++; // ????????? TODO: trying to get an one-hit wonder, this code code should be rewritten... 5840 rStCtrl.Seek( nPos ); 5841 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) 5842 && ( DFF_msofbtDgContainer == nFbt ); 5843 } 5844 if( bOk ) 5845 { 5846 // --> OD 2008-07-28 #156763# 5847 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId ); 5848 // <-- 5849 } 5850 nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5851 // --> OD 2008-07-28 #156763# 5852 ++nDrawingContainerId; 5853 // <-- 5854 } 5855 while( ( rStCtrl.GetError() == 0 ) && ( nPos < nMaxStrPos ) && bOk ); 5856 } 5857 } 5858 5859 5860 // ab hier: Drawing Group Container d.h. Dokument - weit gueltige Daten 5861 // ======================= ======== 5862 // 5863 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, sal_uLong nLenDgg ) 5864 { 5865 sal_uInt8 nVer; 5866 sal_uInt16 nInst; 5867 sal_uInt16 nFbt; 5868 sal_uInt32 nLength; 5869 5870 sal_uLong nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0; 5871 5872 // Nach einem BStore Container suchen 5873 do 5874 { 5875 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5876 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5877 if( DFF_msofbtBstoreContainer == nFbt ) 5878 { 5879 nLenBStoreCont = nLength; break; 5880 } 5881 rSt.SeekRel( nLength ); 5882 } 5883 while( nRead < nLenDgg ); 5884 5885 if( !nLenBStoreCont ) return; 5886 5887 // Im BStore Container alle Header der Container und Atome auslesen und die 5888 // relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen. 5889 // Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit. 5890 5891 const sal_uLong nSkipBLIPLen = 20; // bis zu nBLIPLen zu ueberspringende Bytes 5892 const sal_uLong nSkipBLIPPos = 4; // dahinter bis zu nBLIPPos zu skippen 5893 5894 sal_uInt32 nBLIPLen = 0, nBLIPPos = 0; 5895 5896 nRead = 0; 5897 do 5898 { 5899 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5900 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength; 5901 if( DFF_msofbtBSE == nFbt ) 5902 { 5903 nLenFBSE = nLength; 5904 // ist FBSE gross genug fuer unsere Daten 5905 sal_Bool bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE ); 5906 5907 if( bOk ) 5908 { 5909 rSt.SeekRel( nSkipBLIPLen ); 5910 rSt >> nBLIPLen; 5911 rSt.SeekRel( nSkipBLIPPos ); 5912 rSt >> nBLIPPos; 5913 bOk = rSt.GetError() == 0; 5914 5915 nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4; 5916 } 5917 5918 if( bOk ) 5919 { 5920 // Besonderheit: 5921 // Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist, 5922 // nehmen wir an, dass das Bild IM FBSE drin steht! 5923 if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) ) 5924 nBLIPPos = rSt.Tell() + 4; 5925 5926 // Das hat ja fein geklappt! 5927 // Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben. 5928 nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell()); 5929 5930 if( USHRT_MAX == nBLIPCount ) 5931 nBLIPCount = 1; 5932 else 5933 nBLIPCount++; 5934 5935 // Jetzt die Infos fuer spaetere Zugriffe speichern 5936 pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ), 5937 pBLIPInfos->Count() ); 5938 } 5939 } 5940 rSt.SeekRel( nLength ); 5941 } 5942 while( nRead < nLenBStoreCont ); 5943 } 5944 5945 5946 // ab hier: Drawing Container d.h. Seiten (Blatt, Dia) - weit gueltige Daten 5947 // ================= ====== 5948 // 5949 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, sal_uLong nLenDg, 5950 const unsigned long nDrawingContainerId ) 5951 { 5952 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 5953 5954 sal_uLong nReadDg = 0; 5955 5956 // Wir stehen in einem Drawing Container (je einer pro Seite) 5957 // und muessen nun 5958 // alle enthaltenen Shape Group Container abklappern 5959 do 5960 { 5961 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return; 5962 nReadDg += DFF_COMMON_RECORD_HEADER_SIZE; 5963 // Patriarch gefunden (der oberste Shape Group Container) ? 5964 if( DFF_msofbtSpgrContainer == nFbt ) 5965 { 5966 if(!this->GetShapeGroupContainerData( rSt, nLength, sal_True, nDrawingContainerId )) return; 5967 } 5968 else 5969 // blanker Shape Container ? (ausserhalb vom Shape Group Container) 5970 if( DFF_msofbtSpContainer == nFbt ) 5971 { 5972 if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return; 5973 } 5974 else 5975 rSt.SeekRel( nLength ); 5976 nReadDg += nLength; 5977 } 5978 while( nReadDg < nLenDg ); 5979 } 5980 5981 sal_Bool SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt, 5982 sal_uLong nLenShapeGroupCont, 5983 sal_Bool bPatriarch, 5984 const unsigned long nDrawingContainerId ) 5985 { 5986 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 5987 long nStartShapeGroupCont = rSt.Tell(); 5988 // Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite) 5989 // und muessen nun 5990 // alle enthaltenen Shape Container abklappern 5991 sal_Bool bFirst = !bPatriarch; 5992 sal_uLong nReadSpGrCont = 0; 5993 do 5994 { 5995 if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) ) 5996 return sal_False; 5997 nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE; 5998 // Shape Container ? 5999 if( DFF_msofbtSpContainer == nFbt ) 6000 { 6001 sal_uLong nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX; 6002 if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) ) 6003 return sal_False; 6004 bFirst = sal_False; 6005 } 6006 else 6007 // eingeschachtelter Shape Group Container ? 6008 if( DFF_msofbtSpgrContainer == nFbt ) 6009 { 6010 if ( !this->GetShapeGroupContainerData( rSt, nLength, sal_False, nDrawingContainerId ) ) 6011 return sal_False; 6012 } 6013 else 6014 rSt.SeekRel( nLength ); 6015 nReadSpGrCont += nLength; 6016 } 6017 while( nReadSpGrCont < nLenShapeGroupCont ); 6018 // den Stream wieder korrekt positionieren 6019 rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont ); 6020 return sal_True; 6021 } 6022 6023 sal_Bool SvxMSDffManager::GetShapeContainerData( SvStream& rSt, 6024 sal_uLong nLenShapeCont, 6025 sal_uLong nPosGroup, 6026 const unsigned long nDrawingContainerId ) 6027 { 6028 sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength; 6029 long nStartShapeCont = rSt.Tell(); 6030 // Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group) 6031 // und muessen nun 6032 // die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe) 6033 // und den ersten BStore Verweis (falls vorhanden) entnehmen 6034 sal_uLong nLenShapePropTbl = 0; 6035 sal_uLong nReadSpCont = 0; 6036 6037 // File Offset des Shape-Containers bzw. der Gruppe(!) vermerken 6038 // 6039 sal_uLong nStartOffs = (ULONG_MAX > nPosGroup) ? 6040 nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE; 6041 SvxMSDffShapeInfo aInfo( nStartOffs ); 6042 6043 // duerfte das Shape durch einen Rahmen ersetzt werden ? 6044 // (vorausgesetzt, es zeigt sich, dass es eine TextBox ist, 6045 // und der Text nicht gedreht ist) 6046 sal_Bool bCanBeReplaced = (ULONG_MAX > nPosGroup) ? sal_False : sal_True; 6047 6048 // wir wissen noch nicht, ob es eine TextBox ist 6049 MSO_SPT eShapeType = mso_sptNil; 6050 MSO_WrapMode eWrapMode = mso_wrapSquare; 6051 // sal_Bool bIsTextBox = sal_False; 6052 6053 // Shape analysieren 6054 // 6055 do 6056 { 6057 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return sal_False; 6058 nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE; 6059 // FSP ? 6060 if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) ) 6061 { 6062 // Wir haben den FSP gefunden: Shape Typ und Id vermerken! 6063 eShapeType = (MSO_SPT)nInst; 6064 rSt >> aInfo.nShapeId; 6065 rSt.SeekRel( nLength - 4 ); 6066 nReadSpCont += nLength; 6067 } 6068 else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ? 6069 { 6070 // Wir haben die Property Table gefunden: 6071 // nach der Blip Property suchen! 6072 sal_uLong nPropRead = 0; 6073 sal_uInt16 nPropId; 6074 sal_uInt32 nPropVal; 6075 nLenShapePropTbl = nLength; 6076 // sal_uInt32 nPropCount = nInst; 6077 long nStartShapePropTbl = rSt.Tell(); 6078 // sal_uInt32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6); 6079 do 6080 { 6081 rSt >> nPropId 6082 >> nPropVal; 6083 nPropRead += 6; 6084 6085 switch( nPropId ) 6086 { 6087 case DFF_Prop_txflTextFlow : 6088 //Writer can now handle vertical textflows in its 6089 //native frames, to only need to do this for the 6090 //other two formats 6091 6092 //Writer will handle all textflow except BtoT 6093 if (GetSvxMSDffSettings() & 6094 (SVXMSDFF_SETTINGS_IMPORT_PPT | 6095 SVXMSDFF_SETTINGS_IMPORT_EXCEL)) 6096 { 6097 if( 0 != nPropVal ) 6098 bCanBeReplaced = false; 6099 } 6100 else if ( 6101 (nPropVal != mso_txflHorzN) && 6102 (nPropVal != mso_txflTtoBA) 6103 ) 6104 { 6105 bCanBeReplaced = false; 6106 } 6107 break; 6108 case DFF_Prop_cdirFont : 6109 //Writer can now handle right to left and left 6110 //to right in its native frames, so only do 6111 //this for the other two formats. 6112 if (GetSvxMSDffSettings() & 6113 (SVXMSDFF_SETTINGS_IMPORT_PPT | 6114 SVXMSDFF_SETTINGS_IMPORT_EXCEL)) 6115 { 6116 if( 0 != nPropVal ) 6117 bCanBeReplaced = sal_False; 6118 } 6119 break; 6120 case DFF_Prop_Rotation : 6121 if( 0 != nPropVal ) 6122 bCanBeReplaced = sal_False; 6123 break; 6124 6125 case DFF_Prop_gtextFStrikethrough : 6126 if( ( 0x20002000 & nPropVal ) == 0x20002000 ) 6127 bCanBeReplaced = sal_False; 6128 break; 6129 6130 case DFF_Prop_fc3DLightFace : 6131 if( ( 0x00080008 & nPropVal ) == 0x00080008 ) 6132 bCanBeReplaced = sal_False; 6133 break; 6134 6135 case DFF_Prop_WrapText : 6136 eWrapMode = (MSO_WrapMode)nPropVal; 6137 break; 6138 6139 default: 6140 { 6141 // Bit gesetzt und gueltig? 6142 if( 0x4000 == ( nPropId & 0xC000 ) ) 6143 { 6144 // Blip Property gefunden: BStore Idx vermerken! 6145 nPropRead = nLenShapePropTbl; 6146 } 6147 else if( 0x8000 & nPropId ) 6148 { 6149 // komplexe Prop gefunden: 6150 // Laenge ist immer 6, nur die Laenge der nach der 6151 // eigentlichen Prop-Table anhaengenden Extra-Daten 6152 // ist unterschiedlich 6153 nPropVal = 6; 6154 } 6155 } 6156 break; 6157 } 6158 6159 /* 6160 //JP 21.04.99: Bug 64510 6161 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge 6162 // Performance einbussen hat. 6163 6164 if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig? 6165 { 6166 // Blip Property gefunden: BStore Idx vermerken! 6167 aInfo.nBStoreIdx = nPropVal; // Index im BStore Container 6168 break; 6169 } 6170 else 6171 if( ( ( (DFF_Prop_txflTextFlow == nPropId) 6172 || (DFF_Prop_Rotation == nPropId) 6173 || (DFF_Prop_cdirFont == nPropId) ) 6174 && (0 != nPropVal) ) 6175 6176 || ( (DFF_Prop_gtextFStrikethrough == nPropId) 6177 && ( (0x20002000 & nPropVal) == 0x20002000) ) // also DFF_Prop_gtextFVertical 6178 || ( (DFF_Prop_fc3DLightFace == nPropId) 6179 && ( (0x00080008 & nPropVal) == 0x00080008) ) // also DFF_Prop_f3D 6180 ) 6181 { 6182 bCanBeReplaced = sal_False; // Mist: gedrehter Text oder 3D-Objekt! 6183 } 6184 else 6185 if( DFF_Prop_WrapText == nPropId ) 6186 { 6187 eWrapMode = (MSO_WrapMode)nPropVal; 6188 } 6189 //////////////////////////////////////////////////////////////// 6190 //////////////////////////////////////////////////////////////// 6191 // keine weitere Property-Auswertung: folge beim Shape-Import // 6192 //////////////////////////////////////////////////////////////// 6193 //////////////////////////////////////////////////////////////// 6194 else 6195 if( 0x8000 & nPropId ) 6196 { 6197 // komplexe Prop gefunden: Laenge lesen und ueberspringen 6198 if(!SkipBytes( rSt, nPropVal )) return sal_False; 6199 nPropRead += nPropVal; 6200 } 6201 */ 6202 } 6203 while( nPropRead < nLenShapePropTbl ); 6204 rSt.Seek( nStartShapePropTbl + nLenShapePropTbl ); 6205 nReadSpCont += nLenShapePropTbl; 6206 } 6207 else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) ) // Text-Box-Story-Eintrag gefunden 6208 { 6209 rSt >> aInfo.nTxBxComp; 6210 // --> OD 2008-07-28 #156763# 6211 // Add internal drawing container id to text id. 6212 // Note: The text id uses the first two bytes, while the internal 6213 // drawing container id used the second two bytes. 6214 aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) + 6215 nDrawingContainerId; 6216 DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId, 6217 "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." ); 6218 // <-- 6219 } 6220 else 6221 { 6222 rSt.SeekRel( nLength ); 6223 nReadSpCont += nLength; 6224 } 6225 } 6226 while( nReadSpCont < nLenShapeCont ); 6227 6228 // 6229 // Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern 6230 // 6231 if( aInfo.nShapeId ) 6232 { 6233 // fuer Textboxen ggfs. ersetzen durch Rahmen erlauben 6234 if( bCanBeReplaced 6235 && aInfo.nTxBxComp 6236 && ( 6237 ( eShapeType == mso_sptTextSimple ) 6238 || ( eShapeType == mso_sptTextBox ) 6239 || ( ( ( eShapeType == mso_sptRectangle ) 6240 || ( eShapeType == mso_sptRoundRectangle ) 6241 ) 6242 ) ) ) 6243 { 6244 aInfo.bReplaceByFly = sal_True; 6245 } 6246 pShapeInfos->Insert( new SvxMSDffShapeInfo( aInfo ) ); 6247 pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ), 6248 pShapeOrders->Count() ); 6249 } 6250 6251 // und den Stream wieder korrekt positionieren 6252 rSt.Seek( nStartShapeCont + nLenShapeCont ); 6253 return sal_True; 6254 } 6255 6256 6257 6258 /***************************************************************************** 6259 6260 Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id) 6261 ---------------------------------- 6262 ******************************************************************************/ 6263 sal_Bool SvxMSDffManager::GetShape(sal_uLong nId, SdrObject*& rpShape, 6264 SvxMSDffImportData& rData) 6265 { 6266 SvxMSDffShapeInfo aTmpRec(0, nId); 6267 aTmpRec.bSortByShapeId = sal_True; 6268 6269 sal_uInt16 nFound; 6270 if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) ) 6271 { 6272 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound ); 6273 6274 // eventuell altes Errorflag loeschen 6275 if( rStCtrl.GetError() ) 6276 rStCtrl.ResetError(); 6277 // FilePos des/der Stream(s) merken 6278 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 6279 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 6280 // das Shape im Steuer Stream anspringen 6281 rStCtrl.Seek( rInfo.nFilePos ); 6282 6283 // Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt! 6284 if( rStCtrl.GetError() ) 6285 rStCtrl.ResetError(); 6286 else 6287 rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect ); 6288 6289 // alte FilePos des/der Stream(s) restaurieren 6290 rStCtrl.Seek( nOldPosCtrl ); 6291 if( &rStCtrl != pStData ) 6292 pStData->Seek( nOldPosData ); 6293 return ( 0 != rpShape ); 6294 } 6295 return sal_False; 6296 } 6297 6298 6299 6300 /* Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr) 6301 --------------------------------- 6302 ******************************************************************************/ 6303 sal_Bool SvxMSDffManager::GetBLIP( sal_uLong nIdx_, Graphic& rData, Rectangle* pVisArea ) const 6304 { 6305 sal_Bool bOk = sal_False; // Ergebnisvariable initialisieren 6306 if ( pStData ) 6307 { 6308 // check if a graphic for this blipId is already imported 6309 if ( nIdx_ && pEscherBlipCache ) 6310 { 6311 EscherBlipCacheEntry* pEntry; 6312 for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry; 6313 pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() ) 6314 { 6315 if ( pEntry->nBlip == nIdx_ ) 6316 { /* if this entry is available, then it should be possible 6317 to get the Graphic via GraphicObject */ 6318 GraphicObject aGraphicObject( pEntry->aUniqueID ); 6319 rData = aGraphicObject.GetGraphic(); 6320 if ( rData.GetType() != GRAPHIC_NONE ) 6321 bOk = sal_True; 6322 else 6323 delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove(); 6324 break; 6325 } 6326 } 6327 } 6328 if ( !bOk ) 6329 { 6330 sal_uInt16 nIdx = sal_uInt16( nIdx_ ); 6331 if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return sal_False; 6332 6333 // eventuell alte(s) Errorflag(s) loeschen 6334 if( rStCtrl.GetError() ) 6335 rStCtrl.ResetError(); 6336 if( ( &rStCtrl != pStData ) 6337 && pStData->GetError() ) 6338 pStData->ResetError(); 6339 6340 // FilePos des/der Stream(s) merken 6341 sal_uLong nOldPosCtrl = rStCtrl.Tell(); 6342 sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl; 6343 6344 // passende Info-Struct aus unserem Pointer Array nehmen 6345 SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ]; 6346 6347 // das BLIP Atom im Daten Stream anspringen 6348 pStData->Seek( rInfo.nFilePos ); 6349 // ggfs. Fehlerstatus zuruecksetzen 6350 if( pStData->GetError() ) 6351 pStData->ResetError(); 6352 else 6353 bOk = GetBLIPDirect( *pStData, rData, pVisArea ); 6354 if( pStData2 && !bOk ) 6355 { 6356 // Fehler, aber zweite Chance: es gibt noch einen zweiten 6357 // Datenstream, in dem die Grafik liegen koennte! 6358 if( pStData2->GetError() ) 6359 pStData2->ResetError(); 6360 sal_uLong nOldPosData2 = pStData2->Tell(); 6361 // das BLIP Atom im zweiten Daten Stream anspringen 6362 pStData2->Seek( rInfo.nFilePos ); 6363 // ggfs. Fehlerstatus zuruecksetzen 6364 if( pStData2->GetError() ) 6365 pStData2->ResetError(); 6366 else 6367 bOk = GetBLIPDirect( *pStData2, rData, pVisArea ); 6368 // alte FilePos des zweiten Daten-Stream restaurieren 6369 pStData2->Seek( nOldPosData2 ); 6370 } 6371 // alte FilePos des/der Stream(s) restaurieren 6372 rStCtrl.Seek( nOldPosCtrl ); 6373 if( &rStCtrl != pStData ) 6374 pStData->Seek( nOldPosData ); 6375 6376 if ( bOk ) 6377 { 6378 // create new BlipCacheEntry for this graphic 6379 GraphicObject aGraphicObject( rData ); 6380 if ( !pEscherBlipCache ) 6381 const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List(); 6382 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() ); 6383 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND ); 6384 } 6385 } 6386 } 6387 return bOk; 6388 } 6389 6390 /* Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream) 6391 --------------------------------- 6392 ******************************************************************************/ 6393 sal_Bool SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const 6394 { 6395 sal_uLong nOldPos = rBLIPStream.Tell(); 6396 6397 int nRes = GRFILTER_OPENERROR; // Fehlervariable initialisieren 6398 6399 // nachschauen, ob es sich auch wirklich um ein BLIP handelt 6400 sal_uInt32 nLength; 6401 sal_uInt16 nInst, nFbt( 0 ); 6402 sal_uInt8 nVer; 6403 if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) ) 6404 { 6405 Size aMtfSize100; 6406 sal_Bool bMtfBLIP = sal_False; 6407 sal_Bool bZCodecCompression = sal_False; 6408 // Nun exakt auf den Beginn der eingebetteten Grafik positionieren 6409 sal_uLong nSkip = ( nInst & 0x0001 ) ? 32 : 16; 6410 6411 switch( nInst & 0xFFFE ) 6412 { 6413 case 0x216 : // Metafile header then compressed WMF 6414 case 0x3D4 : // Metafile header then compressed EMF 6415 case 0x542 : // Metafile hd. then compressed PICT 6416 { 6417 rBLIPStream.SeekRel( nSkip + 20 ); 6418 6419 // read in size of metafile in EMUS 6420 rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height(); 6421 6422 // scale to 1/100mm 6423 aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360; 6424 6425 if ( pVisArea ) // seem that we currently are skipping the visarea position 6426 *pVisArea = Rectangle( Point(), aMtfSize100 ); 6427 6428 // skip rest of header 6429 nSkip = 6; 6430 bMtfBLIP = bZCodecCompression = sal_True; 6431 } 6432 break; 6433 case 0x46A : // One byte tag then JPEG (= JFIF) data 6434 case 0x6E0 : // One byte tag then PNG data 6435 case 0x6E2 : // One byte tag then JPEG in CMYK color space 6436 case 0x7A8 : 6437 nSkip += 1; // One byte tag then DIB data 6438 break; 6439 } 6440 rBLIPStream.SeekRel( nSkip ); 6441 6442 SvStream* pGrStream = &rBLIPStream; 6443 SvMemoryStream* pOut = NULL; 6444 if( bZCodecCompression ) 6445 { 6446 pOut = new SvMemoryStream( 0x8000, 0x4000 ); 6447 ZCodec aZCodec( 0x8000, 0x8000 ); 6448 aZCodec.BeginCompression(); 6449 aZCodec.Decompress( rBLIPStream, *pOut ); 6450 aZCodec.EndCompression(); 6451 pOut->Seek( STREAM_SEEK_TO_BEGIN ); 6452 pOut->SetResizeOffset( 0 ); // sj: #i102257# setting ResizeOffset of 0 prevents from seeking 6453 // behind the stream end (allocating too much memory) 6454 pGrStream = pOut; 6455 } 6456 6457 //#define DBG_EXTRACTGRAPHICS 6458 #ifdef DBG_EXTRACTGRAPHICS 6459 6460 static sal_Int32 nCount; 6461 6462 String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) ); 6463 aFileName.Append( String::CreateFromInt32( nCount++ ) ); 6464 switch( nInst &~ 1 ) 6465 { 6466 case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break; 6467 case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break; 6468 case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break; 6469 case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break; 6470 case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break; 6471 case 0x6e2 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break; 6472 case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break; 6473 } 6474 6475 String aURLStr; 6476 6477 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) ) 6478 { 6479 INetURLObject aURL( aURLStr ); 6480 6481 aURL.removeSegment(); 6482 aURL.removeFinalSlash(); 6483 aURL.Append( aFileName ); 6484 6485 SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE ); 6486 6487 if( pDbgOut ) 6488 { 6489 if ( bZCodecCompression ) 6490 { 6491 pOut->Seek( STREAM_SEEK_TO_END ); 6492 pDbgOut->Write( pOut->GetData(), pOut->Tell() ); 6493 pOut->Seek( STREAM_SEEK_TO_BEGIN ); 6494 } 6495 else 6496 { 6497 sal_Int32 nDbgLen = nLength - nSkip; 6498 if ( nDbgLen ) 6499 { 6500 sal_Char* pDat = new sal_Char[ nDbgLen ]; 6501 pGrStream->Read( pDat, nDbgLen ); 6502 pDbgOut->Write( pDat, nDbgLen ); 6503 pGrStream->SeekRel( -nDbgLen ); 6504 delete[] pDat; 6505 } 6506 } 6507 6508 delete pDbgOut; 6509 } 6510 } 6511 #endif 6512 6513 if( ( nInst & 0xFFFE ) == 0x7A8 ) 6514 { // DIBs direkt holen 6515 Bitmap aNew; 6516 if( aNew.Read( *pGrStream, sal_False ) ) 6517 { 6518 rData = Graphic( aNew ); 6519 nRes = GRFILTER_OK; 6520 } 6521 } 6522 else 6523 { // und unsere feinen Filter darauf loslassen 6524 GraphicFilter* pGF = GraphicFilter::GetGraphicFilter(); 6525 String aEmptyStr; 6526 nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW ); 6527 6528 // SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems, 6529 // then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the 6530 // scaling has been implemented does not happen anymore. 6531 // 6532 // For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the 6533 // dxarray is empty (this has been solved in wmf/emf but not for pict) 6534 if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) ) 6535 { 6536 if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) ) 6537 { // #75956#, scaling does not work properly, if the graphic is less than 1cm 6538 GDIMetaFile aMtf( rData.GetGDIMetaFile() ); 6539 const Size aOldSize( aMtf.GetPrefSize() ); 6540 6541 if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) && 6542 aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) ) 6543 { 6544 aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(), 6545 (double) aMtfSize100.Height() / aOldSize.Height() ); 6546 aMtf.SetPrefSize( aMtfSize100 ); 6547 aMtf.SetPrefMapMode( MAP_100TH_MM ); 6548 rData = aMtf; 6549 } 6550 } 6551 } 6552 } 6553 // ggfs. Fehlerstatus zuruecksetzen 6554 if ( ERRCODE_IO_PENDING == pGrStream->GetError() ) 6555 pGrStream->ResetError(); 6556 delete pOut; 6557 } 6558 rBLIPStream.Seek( nOldPos ); // alte FilePos des Streams restaurieren 6559 6560 return ( GRFILTER_OK == nRes ); // Ergebniss melden 6561 } 6562 6563 /* static */ 6564 sal_Bool SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn) 6565 { 6566 rRec.nFilePos = rIn.Tell(); 6567 return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer, 6568 rRec.nRecInstance, 6569 rRec.nRecType, 6570 rRec.nRecLen ); 6571 } 6572 6573 6574 /* auch static */ 6575 sal_Bool SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt, 6576 sal_uInt8& rVer, 6577 sal_uInt16& rInst, 6578 sal_uInt16& rFbt, 6579 sal_uInt32& rLength ) 6580 { 6581 sal_uInt16 nTmp; 6582 rSt >> nTmp >> rFbt >> rLength; 6583 rVer = sal::static_int_cast< sal_uInt8 >(nTmp & 15); 6584 rInst = nTmp >> 4; 6585 if ( rLength > ( SAL_MAX_UINT32 - rSt.Tell() ) ) // preserving overflow, optimal would be to check 6586 rSt.SetError( SVSTREAM_FILEFORMAT_ERROR ); // the record size against the parent header 6587 return rSt.GetError() == 0; 6588 } 6589 6590 6591 6592 6593 sal_Bool SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, sal_uLong nDatLen, 6594 char*& rpBuff, sal_uInt32& rBuffLen ) const 6595 { 6596 if( nDatLen ) 6597 { 6598 rpBuff = new (std::nothrow) char[ nDatLen ]; 6599 rBuffLen = nDatLen; 6600 rStData.Read( rpBuff, nDatLen ); 6601 } 6602 return sal_True; 6603 } 6604 6605 sal_Bool SvxMSDffManager::ProcessClientData(SvStream& rStData, sal_uLong nDatLen, 6606 char*& rpBuff, sal_uInt32& rBuffLen ) const 6607 { 6608 if( nDatLen ) 6609 { 6610 rpBuff = new (std::nothrow) char[ nDatLen ]; 6611 if ( rpBuff ) 6612 { 6613 rBuffLen = nDatLen; 6614 rStData.Read( rpBuff, nDatLen ); 6615 } 6616 } 6617 return sal_True; 6618 } 6619 6620 6621 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ ) 6622 { 6623 return; // wird von SJ im Draw ueberladen 6624 } 6625 6626 sal_uLong SvxMSDffManager::Calc_nBLIPPos( sal_uLong nOrgVal, sal_uLong /* nStreamPos */ ) const 6627 { 6628 return nOrgVal; 6629 } 6630 6631 sal_Bool SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const 6632 { 6633 return sal_False; 6634 } 6635 6636 sal_Bool SvxMSDffManager::ShapeHasText( sal_uLong /* nShapeId */, sal_uLong /* nFilePos */ ) const 6637 { 6638 return sal_True; 6639 } 6640 6641 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup> 6642 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId, 6643 const Graphic& rGrf, 6644 const Rectangle& rBoundRect, 6645 const Rectangle& rVisArea, 6646 const int /* _nCalledByGroup */, 6647 sal_Int64 nAspect ) const 6648 // <-- 6649 { 6650 SdrObject* pRet = 0; 6651 String sStorageName; 6652 SvStorageRef xSrcStg; 6653 ErrCode nError = ERRCODE_NONE; 6654 uno::Reference < embed::XStorage > xDstStg; 6655 if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg )) 6656 pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg, 6657 rGrf, rBoundRect, rVisArea, pStData, nError, 6658 nSvxMSDffOLEConvFlags, nAspect ); 6659 return pRet; 6660 } 6661 6662 sal_Bool SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf ) 6663 { 6664 String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) ); 6665 SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream ); 6666 xStm->SetVersion( pStor->GetVersion() ); 6667 xStm->SetBufferSize( 8192 ); 6668 6669 sal_uInt16 nAspect = ASPECT_CONTENT; 6670 sal_uLong nAdviseModes = 2; 6671 6672 Impl_OlePres aEle( FORMAT_GDIMETAFILE ); 6673 // Die Groesse in 1/100 mm umrechnen 6674 // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird, 6675 // versucht SV einen BestMatchden richtigen Wert zu raten. 6676 Size aSize = rMtf.GetPrefSize(); 6677 MapMode aMMSrc = rMtf.GetPrefMapMode(); 6678 MapMode aMMDst( MAP_100TH_MM ); 6679 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst ); 6680 aEle.SetSize( aSize ); 6681 aEle.SetAspect( nAspect ); 6682 aEle.SetAdviseFlags( nAdviseModes ); 6683 aEle.SetMtf( rMtf ); 6684 aEle.Write( *xStm ); 6685 6686 xStm->SetBufferSize( 0 ); 6687 return xStm->GetError() == SVSTREAM_OK; 6688 } 6689 6690 struct ClsIDs { 6691 sal_uInt32 nId; 6692 const sal_Char* pSvrName; 6693 const sal_Char* pDspName; 6694 }; 6695 static ClsIDs aClsIDs[] = { 6696 6697 { 0x000212F0, "MSWordArt", "Microsoft Word Art" }, 6698 { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" }, 6699 6700 // MS Apps 6701 { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" }, 6702 { 0x00030001, "ExcelChart", "Microsoft Excel Chart" }, 6703 { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" }, 6704 { 0x00030003, "WordDocument", "Microsoft Word Document" }, 6705 { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" }, 6706 { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"}, 6707 { 0x00030006, "MSGraph", "Microsoft Graph" }, 6708 { 0x00030007, "MSDraw", "Microsoft Draw" }, 6709 { 0x00030008, "Note-It", "Microsoft Note-It" }, 6710 { 0x00030009, "WordArt", "Microsoft Word Art" }, 6711 { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" }, 6712 { 0x0003000b, "Equation", "Microsoft Equation Editor" }, 6713 { 0x0003000c, "Package", "Package" }, 6714 { 0x0003000d, "SoundRec", "Sound" }, 6715 { 0x0003000e, "MPlayer", "Media Player" }, 6716 // MS Demos 6717 { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" }, 6718 { 0x00030010, "Srtest", "OLE 1.0 Test Demo" }, 6719 { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" }, 6720 { 0x00030012, "OleDemo", "OLE 1.0 Demo" }, 6721 6722 // Coromandel / Dorai Swamy / 718-793-7963 6723 { 0x00030013, "CoromandelIntegra", "Coromandel Integra" }, 6724 { 0x00030014, "CoromandelObjServer","Coromandel Object Server" }, 6725 6726 // 3-d Visions Corp / Peter Hirsch / 310-325-1339 6727 { 0x00030015, "StanfordGraphics", "Stanford Graphics" }, 6728 6729 // Deltapoint / Nigel Hearne / 408-648-4000 6730 { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" }, 6731 { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" }, 6732 6733 // Corel / Richard V. Woodend / 613-728-8200 x1153 6734 { 0x00030018, "PhotoPaint", "Corel PhotoPaint" }, 6735 { 0x00030019, "CShow", "Corel Show" }, 6736 { 0x0003001a, "CorelChart", "Corel Chart" }, 6737 { 0x0003001b, "CDraw", "Corel Draw" }, 6738 6739 // Inset Systems / Mark Skiba / 203-740-2400 6740 { 0x0003001c, "HJWIN1.0", "Inset Systems" }, 6741 6742 // Mark V Systems / Mark McGraw / 818-995-7671 6743 { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" }, 6744 6745 // IdentiTech / Mike Gilger / 407-951-9503 6746 { 0x0003001e, "FYI", "IdentiTech FYI" }, 6747 { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" }, 6748 6749 // Inventa Corporation / Balaji Varadarajan / 408-987-0220 6750 { 0x00030020, "Stickynote", "Inventa Sticky Note" }, 6751 6752 // ShapeWare Corp. / Lori Pearce / 206-467-6723 6753 { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" }, 6754 { 0x00030022, "ImportServer", "Spaheware Import Server" }, 6755 6756 // test app SrTest 6757 { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" }, 6758 6759 // test app ClTest. Doesn't really work as a server but is in reg db 6760 { 0x00030025, "Cltest", "OLE 1.0 Client Test" }, 6761 6762 // Microsoft ClipArt Gallery Sherry Larsen-Holmes 6763 { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" }, 6764 // Microsoft Project Cory Reina 6765 { 0x00030027, "MSProject", "Microsoft Project" }, 6766 6767 // Microsoft Works Chart 6768 { 0x00030028, "MSWorksChart", "Microsoft Works Chart" }, 6769 6770 // Microsoft Works Spreadsheet 6771 { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" }, 6772 6773 // AFX apps - Dean McCrory 6774 { 0x0003002A, "MinSvr", "AFX Mini Server" }, 6775 { 0x0003002B, "HierarchyList", "AFX Hierarchy List" }, 6776 { 0x0003002C, "BibRef", "AFX BibRef" }, 6777 { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" }, 6778 { 0x0003002E, "TestServ", "AFX Test Server" }, 6779 6780 // Ami Pro 6781 { 0x0003002F, "AmiProDocument", "Ami Pro Document" }, 6782 6783 // WordPerfect Presentations For Windows 6784 { 0x00030030, "WPGraphics", "WordPerfect Presentation" }, 6785 { 0x00030031, "WPCharts", "WordPerfect Chart" }, 6786 6787 // MicroGrafx Charisma 6788 { 0x00030032, "Charisma", "MicroGrafx Charisma" }, 6789 { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" }, 6790 { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" }, 6791 // MicroGrafx Draw 6792 { 0x00030035, "Draw", "MicroGrafx Draw" }, 6793 // MicroGrafx Designer 6794 { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" }, 6795 6796 // STAR DIVISION 6797 // { 0x000424CA, "StarMath", "StarMath 1.0" }, 6798 { 0x00043AD2, "FontWork", "Star FontWork" }, 6799 // { 0x000456EE, "StarMath2", "StarMath 2.0" }, 6800 6801 { 0, "", "" } }; 6802 6803 6804 sal_Bool SvxMSDffManager::ConvertToOle2( SvStream& rStm, sal_uInt32 nReadLen, 6805 const GDIMetaFile * pMtf, const SotStorageRef& rDest ) 6806 { 6807 sal_Bool bMtfRead = sal_False; 6808 SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ), 6809 STREAM_WRITE| STREAM_SHARE_DENYALL ); 6810 if( xOle10Stm->GetError() ) 6811 return sal_False; 6812 6813 sal_uInt32 nType; 6814 sal_uInt32 nRecType; 6815 sal_uInt32 nStrLen; 6816 String aSvrName; 6817 sal_uInt32 nDummy0; 6818 sal_uInt32 nDummy1; 6819 sal_uInt32 nDataLen; 6820 sal_uInt8 * pData; 6821 sal_uInt32 nBytesRead = 0; 6822 do 6823 { 6824 rStm >> nType; 6825 rStm >> nRecType; 6826 rStm >> nStrLen; 6827 if( nStrLen ) 6828 { 6829 if( 0x10000L > nStrLen ) 6830 { 6831 sal_Char * pBuf = new sal_Char[ nStrLen ]; 6832 rStm.Read( pBuf, nStrLen ); 6833 aSvrName.Assign( String( pBuf, (sal_uInt16) nStrLen-1, gsl_getSystemTextEncoding() ) ); 6834 delete[] pBuf; 6835 } 6836 else 6837 break; 6838 } 6839 rStm >> nDummy0; 6840 rStm >> nDummy1; 6841 rStm >> nDataLen; 6842 6843 nBytesRead += 6 * sizeof( sal_uInt32 ) + nStrLen + nDataLen; 6844 6845 if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen ) 6846 { 6847 if( xOle10Stm.Is() ) 6848 { 6849 pData = new sal_uInt8[ nDataLen ]; 6850 if( !pData ) 6851 return sal_False; 6852 6853 rStm.Read( pData, nDataLen ); 6854 6855 // write to ole10 stream 6856 *xOle10Stm << nDataLen; 6857 xOle10Stm->Write( pData, nDataLen ); 6858 xOle10Stm = SotStorageStreamRef(); 6859 6860 // set the compobj stream 6861 ClsIDs* pIds; 6862 for( pIds = aClsIDs; pIds->nId; pIds++ ) 6863 { 6864 if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) ) 6865 break; 6866 } 6867 // SvGlobalName* pClsId = NULL; 6868 String aShort, aFull; 6869 if( pIds->nId ) 6870 { 6871 // gefunden! 6872 sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName ); 6873 rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt, 6874 String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) ); 6875 } 6876 else 6877 { 6878 sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName ); 6879 rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName ); 6880 } 6881 6882 delete[] pData; 6883 } 6884 else if( nRecType == 5 && !pMtf ) 6885 { 6886 sal_uLong nPos = rStm.Tell(); 6887 sal_uInt16 sz[4]; 6888 rStm.Read( sz, 8 ); 6889 //rStm.SeekRel( 8 ); 6890 Graphic aGraphic; 6891 if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() ) 6892 { 6893 const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile(); 6894 MakeContentStream( rDest, rMtf ); 6895 bMtfRead = sal_True; 6896 } 6897 // set behind the data 6898 rStm.Seek( nPos + nDataLen ); 6899 } 6900 else 6901 rStm.SeekRel( nDataLen ); 6902 } 6903 } while( !rStm.IsEof() && nReadLen >= nBytesRead ); 6904 6905 if( !bMtfRead && pMtf ) 6906 { 6907 MakeContentStream( rDest, *pMtf ); 6908 return sal_True; 6909 } 6910 6911 return sal_False; 6912 } 6913 6914 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName ) 6915 { 6916 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) 6917 || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) ) 6918 return "swriter"; 6919 else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) 6920 || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) ) 6921 return "scalc"; 6922 else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) 6923 || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) 6924 return "simpress"; 6925 else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) 6926 || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) 6927 return "sdraw"; 6928 else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) 6929 || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) ) 6930 return "smath"; 6931 else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) 6932 || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) 6933 return "schart"; 6934 return 0; 6935 } 6936 6937 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName ) 6938 { 6939 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) ) 6940 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) ); 6941 6942 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) ) 6943 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) ); 6944 6945 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) ) 6946 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) ); 6947 6948 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) ) 6949 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) ); 6950 6951 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) ) 6952 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) ); 6953 6954 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) 6955 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) ); 6956 6957 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) ) 6958 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) ); 6959 6960 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) 6961 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) ); 6962 6963 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) ) 6964 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) ); 6965 6966 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) ) 6967 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) ); 6968 6969 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) ) 6970 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) ); 6971 6972 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) 6973 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) ); 6974 6975 return ::rtl::OUString(); 6976 } 6977 6978 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > SvxMSDffManager::CheckForConvertToSOObj( sal_uInt32 nConvertFlags, 6979 SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage, 6980 const Graphic& rGrf, 6981 const Rectangle& rVisArea ) 6982 { 6983 uno::Reference < embed::XEmbeddedObject > xObj; 6984 SvGlobalName aStgNm = rSrcStg.GetClassName(); 6985 const char* pName = GetInternalServerName_Impl( aStgNm ); 6986 String sStarName; 6987 if ( pName ) 6988 sStarName = String::CreateFromAscii( pName ); 6989 else if ( nConvertFlags ) 6990 { 6991 static struct _ObjImpType 6992 { 6993 sal_uInt32 nFlag; 6994 const char* pFactoryNm; 6995 // GlobalNameId 6996 sal_uInt32 n1; 6997 sal_uInt16 n2, n3; 6998 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15; 6999 } aArr[] = { 7000 { OLE_MATHTYPE_2_STARMATH, "smath", 7001 0x0002ce02L, 0x0000, 0x0000, 7002 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7003 { OLE_MATHTYPE_2_STARMATH, "smath", 7004 0x00021700L, 0x0000, 0x0000, 7005 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7006 { OLE_WINWORD_2_STARWRITER, "swriter", 7007 0x00020906L, 0x0000, 0x0000, 7008 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7009 { OLE_EXCEL_2_STARCALC, "scalc", // Excel table 7010 0x00020810L, 0x0000, 0x0000, 7011 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7012 { OLE_EXCEL_2_STARCALC, "scalc", // Excel chart 7013 0x00020820L, 0x0000, 0x0000, 7014 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7015 // 114465: additional Excel OLE chart classId to above. 7016 { OLE_EXCEL_2_STARCALC, "scalc", 7017 0x00020821L, 0x0000, 0x0000, 7018 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }, 7019 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint presentation 7020 0x64818d10L, 0x4f9b, 0x11cf, 7021 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 }, 7022 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint slide 7023 0x64818d11L, 0x4f9b, 0x11cf, 7024 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 }, 7025 { 0, 0, 7026 0, 0, 0, 7027 0, 0, 0, 0, 0, 0, 0, 0 } 7028 }; 7029 7030 for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr ) 7031 { 7032 if( nConvertFlags & pArr->nFlag ) 7033 { 7034 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3, 7035 pArr->b8, pArr->b9, pArr->b10, pArr->b11, 7036 pArr->b12, pArr->b13, pArr->b14, pArr->b15 ); 7037 7038 if ( aStgNm == aTypeName ) 7039 { 7040 sStarName = String::CreateFromAscii( pArr->pFactoryNm ); 7041 break; 7042 } 7043 } 7044 } 7045 } 7046 7047 if ( sStarName.Len() ) 7048 { 7049 //TODO/MBA: check if (and when) storage and stream will be destroyed! 7050 const SfxFilter* pFilter = 0; 7051 SvMemoryStream* pStream = new SvMemoryStream; 7052 if ( pName ) 7053 { 7054 // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also 7055 SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ ); 7056 *xStr >> *pStream; 7057 } 7058 else 7059 { 7060 SfxFilterMatcher aMatch( sStarName ); 7061 SotStorageRef xStorage = new SotStorage( sal_False, *pStream ); 7062 rSrcStg.CopyTo( xStorage ); 7063 xStorage->Commit(); 7064 xStorage.Clear(); 7065 String aType = SfxFilter::GetTypeFromStorage( rSrcStg ); 7066 if ( aType.Len() ) 7067 pFilter = aMatch.GetFilter4EA( aType ); 7068 } 7069 7070 if ( pName || pFilter ) 7071 { 7072 //Reuse current ole name 7073 String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj))); 7074 aDstStgName += String::CreateFromInt32(nMSOleObjCntr); 7075 7076 ::rtl::OUString aFilterName; 7077 if ( pFilter ) 7078 aFilterName = pFilter->GetName(); 7079 else 7080 aFilterName = GetFilterNameFromClassID_Impl( aStgNm ); 7081 7082 uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2); 7083 aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) ); 7084 uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream ); 7085 aMedium[0].Value <<= xStream; 7086 aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 7087 aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ); 7088 7089 if ( aFilterName.getLength() ) 7090 { 7091 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); 7092 aMedium[2].Value <<= aFilterName; 7093 } 7094 7095 ::rtl::OUString aName( aDstStgName ); 7096 comphelper::EmbeddedObjectContainer aCnt( rDestStorage ); 7097 xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); 7098 7099 if ( !xObj.is() ) 7100 { 7101 if( aFilterName.getLength() ) 7102 { 7103 // throw the filter parameter away as workaround 7104 aMedium.realloc( 2 ); 7105 xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); 7106 } 7107 7108 if ( !xObj.is() ) 7109 return xObj; 7110 } 7111 7112 // TODO/LATER: ViewAspect must be passed from outside! 7113 sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT; 7114 7115 // JP 26.10.2001: Bug 93374 / 91928 the writer 7116 // objects need the correct visarea needs the 7117 // correct visarea, but this is not true for 7118 // PowerPoint (see bugdoc 94908b) 7119 // SJ: 19.11.2001 bug 94908, also chart objects 7120 // needs the correct visarea 7121 7122 // If pName is set this is an own embedded object, it should have the correct size internally 7123 // TODO/LATER: it might make sence in future to set the size stored in internal object 7124 if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) ) 7125 { 7126 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) ); 7127 Size aSz; 7128 if ( rVisArea.IsEmpty() ) 7129 aSz = lcl_GetPrefSize(rGrf, aMapMode ); 7130 else 7131 { 7132 aSz = rVisArea.GetSize(); 7133 aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode ); 7134 } 7135 7136 // don't modify the object 7137 //TODO/LATER: remove those hacks, that needs to be done differently! 7138 //xIPObj->EnableSetModified( sal_False ); 7139 awt::Size aSize; 7140 aSize.Width = aSz.Width(); 7141 aSize.Height = aSz.Height(); 7142 xObj->setVisualAreaSize( nViewAspect, aSize ); 7143 //xIPObj->EnableSetModified( sal_True ); 7144 } 7145 else if ( sStarName.EqualsAscii( "smath" ) ) 7146 { // SJ: force the object to recalc its visarea 7147 //TODO/LATER: wait for PrinterChangeNotification 7148 //xIPObj->OnDocumentPrinterChanged( NULL ); 7149 } 7150 } 7151 } 7152 7153 return xObj; 7154 } 7155 7156 // TODO/MBA: code review and testing! 7157 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage( 7158 const String& rStorageName, 7159 SotStorageRef& rSrcStorage, 7160 const uno::Reference < embed::XStorage >& xDestStorage, 7161 const Graphic& rGrf, 7162 const Rectangle& rBoundRect, 7163 const Rectangle& rVisArea, 7164 SvStream* pDataStrm, 7165 ErrCode& rError, 7166 sal_uInt32 nConvertFlags, 7167 sal_Int64 nReccomendedAspect ) 7168 { 7169 sal_Int64 nAspect = nReccomendedAspect; 7170 SdrOle2Obj* pRet = 0; 7171 if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() ) 7172 { 7173 comphelper::EmbeddedObjectContainer aCnt( xDestStorage ); 7174 // Ist der 01Ole-Stream ueberhaupt vorhanden ? 7175 // ( ist er z.B. bei FontWork nicht ) 7176 // Wenn nicht -> Einbindung als Grafik 7177 sal_Bool bValidStorage = sal_False; 7178 String aDstStgName( String::CreateFromAscii( 7179 RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj))); 7180 7181 aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr ); 7182 7183 { 7184 SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName, 7185 STREAM_READWRITE| STREAM_SHARE_DENYALL ); 7186 if( xObjStg.Is() ) 7187 { 7188 { 7189 sal_uInt8 aTestA[10]; // exist the \1CompObj-Stream ? 7190 SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream( 7191 String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"), 7192 RTL_TEXTENCODING_MS_1252 )); 7193 bValidStorage = xSrcTst.Is() && sizeof( aTestA ) == 7194 xSrcTst->Read( aTestA, sizeof( aTestA ) ); 7195 if( !bValidStorage ) 7196 { 7197 // or the \1Ole-Stream ? 7198 xSrcTst = xObjStg->OpenSotStream( 7199 String(RTL_CONSTASCII_STRINGPARAM("\1Ole"), 7200 RTL_TEXTENCODING_MS_1252 )); 7201 bValidStorage = xSrcTst.Is() && sizeof(aTestA) == 7202 xSrcTst->Read(aTestA, sizeof(aTestA)); 7203 } 7204 } 7205 7206 if( bValidStorage ) 7207 { 7208 if ( nAspect != embed::Aspects::MSOLE_ICON ) 7209 { 7210 // check whether the object is iconified one 7211 // usually this information is already known, the only exception 7212 // is a kind of embedded objects in Word documents 7213 // TODO/LATER: should the caller be notified if the aspect changes in future? 7214 7215 SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream( 7216 String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ), 7217 STREAM_STD_READ | STREAM_NOCREATE ); 7218 if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() ) 7219 { 7220 sal_uInt8 nByte = 0; 7221 *xObjInfoSrc >> nByte; 7222 if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON ) 7223 nAspect = embed::Aspects::MSOLE_ICON; 7224 } 7225 } 7226 7227 uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj( 7228 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea )); 7229 if ( xObj.is() ) 7230 { 7231 svt::EmbeddedObjectRef aObj( xObj, nAspect ); 7232 7233 // TODO/LATER: need MediaType 7234 aObj.SetGraphic( rGrf, ::rtl::OUString() ); 7235 7236 // TODO/MBA: check setting of PersistName 7237 pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false); 7238 // we have the Object, don't create another 7239 bValidStorage = false; 7240 } 7241 } 7242 } 7243 } 7244 7245 if( bValidStorage ) 7246 { 7247 // object is not an own object 7248 SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE ); 7249 7250 if ( xObjStor.Is() ) 7251 { 7252 SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ ); 7253 xSrcStor->CopyTo( xObjStor ); 7254 7255 if( !xObjStor->GetError() ) 7256 xObjStor->Commit(); 7257 7258 if( xObjStor->GetError() ) 7259 { 7260 rError = xObjStor->GetError(); 7261 bValidStorage = sal_False; 7262 } 7263 else if( !xObjStor.Is() ) 7264 bValidStorage = sal_False; 7265 } 7266 } 7267 else if( pDataStrm ) 7268 { 7269 sal_uInt32 nLen, nDummy; 7270 *pDataStrm >> nLen >> nDummy; 7271 if( SVSTREAM_OK != pDataStrm->GetError() || 7272 // Id in BugDoc - exist there other Ids? 7273 // The ConvertToOle2 - does not check for consistent 7274 0x30008 != nDummy ) 7275 bValidStorage = sal_False; 7276 else 7277 { 7278 // or is it an OLE-1 Stream in the DataStream? 7279 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName ); 7280 //TODO/MBA: remove metafile conversion from ConvertToOle2 7281 //when is this code used?! 7282 GDIMetaFile aMtf; 7283 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor ); 7284 xObjStor->Commit(); 7285 } 7286 } 7287 7288 if( bValidStorage ) 7289 { 7290 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName ); 7291 if( xObj.is() ) 7292 { 7293 // the visual area must be retrieved from the metafile (object doesn't know it so far) 7294 7295 if ( nAspect != embed::Aspects::MSOLE_ICON ) 7296 { 7297 // working with visual area can switch the object to running state 7298 awt::Size aAwtSz; 7299 try 7300 { 7301 // the provided visual area should be used, if there is any 7302 if ( rVisArea.IsEmpty() ) 7303 { 7304 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) ); 7305 Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit))); 7306 aAwtSz.Width = aSz.Width(); 7307 aAwtSz.Height = aSz.Height(); 7308 } 7309 else 7310 { 7311 aAwtSz.Width = rVisArea.GetWidth(); 7312 aAwtSz.Height = rVisArea.GetHeight(); 7313 } 7314 //xInplaceObj->EnableSetModified( sal_False ); 7315 xObj->setVisualAreaSize( nAspect, aAwtSz ); 7316 //xInplaceObj->EnableSetModified( sal_True );*/ 7317 } 7318 catch( uno::Exception& ) 7319 { 7320 OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" ); 7321 } 7322 } 7323 7324 svt::EmbeddedObjectRef aObj( xObj, nAspect ); 7325 7326 // TODO/LATER: need MediaType 7327 aObj.SetGraphic( rGrf, ::rtl::OUString() ); 7328 7329 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false); 7330 } 7331 } 7332 } 7333 7334 return pRet; 7335 } 7336 7337 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const 7338 { 7339 SdrObject* pRet = NULL; 7340 7341 if(120 >= sal_uInt16(eTyp)) 7342 { 7343 pRet = new SdrRectObj(); 7344 } 7345 7346 DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM"); 7347 7348 return pRet; 7349 } 7350 7351 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, 7352 const String& rPropName, sal_Bool bTestPropertyAvailability ) 7353 { 7354 sal_Bool bRetValue = sal_True; 7355 if ( bTestPropertyAvailability ) 7356 { 7357 bRetValue = sal_False; 7358 try 7359 { 7360 uno::Reference< beans::XPropertySetInfo > 7361 aXPropSetInfo( rXPropSet->getPropertySetInfo() ); 7362 if ( aXPropSetInfo.is() ) 7363 bRetValue = aXPropSetInfo->hasPropertyByName( rPropName ); 7364 } 7365 catch( uno::Exception& ) 7366 { 7367 bRetValue = sal_False; 7368 } 7369 } 7370 if ( bRetValue ) 7371 { 7372 try 7373 { 7374 rXPropSet->setPropertyValue( rPropName, rAny ); 7375 bRetValue = sal_True; 7376 } 7377 catch( uno::Exception& ) 7378 { 7379 bRetValue = sal_False; 7380 } 7381 } 7382 return bRetValue; 7383 } 7384 7385 SvxMSDffImportRec::SvxMSDffImportRec() 7386 : pObj( 0 ), 7387 pWrapPolygon(0), 7388 pClientAnchorBuffer( 0 ), 7389 nClientAnchorLen( 0 ), 7390 pClientDataBuffer( 0 ), 7391 nClientDataLen( 0 ), 7392 nXAlign( 0 ), // position n cm from left 7393 nXRelTo( 2 ), // relative to column 7394 nYAlign( 0 ), // position n cm below 7395 nYRelTo( 2 ), // relative to paragraph 7396 nLayoutInTableCell( 0 ), // element is laid out in table cell 7397 nTextRotationAngle( 0 ), 7398 nDxTextLeft( 144 ), 7399 nDyTextTop( 72 ), 7400 nDxTextRight( 144 ), 7401 nDyTextBottom( 72 ), 7402 nDxWrapDistLeft( 0 ), 7403 nDyWrapDistTop( 0 ), 7404 nDxWrapDistRight( 0 ), 7405 nDyWrapDistBottom(0 ), 7406 nCropFromTop( 0 ), 7407 nCropFromBottom( 0 ), 7408 nCropFromLeft( 0 ), 7409 nCropFromRight( 0 ), 7410 aTextId( 0, 0 ), 7411 nNextShapeId( 0 ), 7412 nShapeId( 0 ), 7413 eShapeType( mso_sptNil ) 7414 { 7415 eLineStyle = mso_lineSimple; // GPF-Bug #66227# 7416 bDrawHell = sal_False; 7417 bHidden = sal_False; 7418 // bInGroup = sal_False; 7419 bReplaceByFly = sal_False; 7420 bLastBoxInChain = sal_True; 7421 bHasUDefProp = sal_False; // was the DFF_msofbtUDefProp record set? 7422 bVFlip = sal_False; 7423 bHFlip = sal_False; 7424 bAutoWidth = sal_False; 7425 } 7426 7427 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy) 7428 : pObj( rCopy.pObj ), 7429 nXAlign( rCopy.nXAlign ), 7430 nXRelTo( rCopy.nXRelTo ), 7431 nYAlign( rCopy.nYAlign ), 7432 nYRelTo( rCopy.nYRelTo ), 7433 nLayoutInTableCell( rCopy.nLayoutInTableCell ), 7434 nTextRotationAngle( rCopy.nTextRotationAngle ), 7435 nDxTextLeft( rCopy.nDxTextLeft ), 7436 nDyTextTop( rCopy.nDyTextTop ), 7437 nDxTextRight( rCopy.nDxTextRight ), 7438 nDyTextBottom( rCopy.nDyTextBottom ), 7439 nDxWrapDistLeft( rCopy.nDxWrapDistLeft ), 7440 nDyWrapDistTop( rCopy.nDyWrapDistTop ), 7441 nDxWrapDistRight( rCopy.nDxWrapDistRight ), 7442 nDyWrapDistBottom(rCopy.nDyWrapDistBottom ), 7443 nCropFromTop( rCopy.nCropFromTop ), 7444 nCropFromBottom( rCopy.nCropFromBottom ), 7445 nCropFromLeft( rCopy.nCropFromLeft ), 7446 nCropFromRight( rCopy.nCropFromRight ), 7447 aTextId( rCopy.aTextId ), 7448 nNextShapeId( rCopy.nNextShapeId ), 7449 nShapeId( rCopy.nShapeId ), 7450 eShapeType( rCopy.eShapeType ) 7451 { 7452 eLineStyle = rCopy.eLineStyle; // GPF-Bug #66227# 7453 bDrawHell = rCopy.bDrawHell; 7454 bHidden = rCopy.bHidden; 7455 // bInGroup = rCopy.bInGroup; 7456 bReplaceByFly = rCopy.bReplaceByFly; 7457 bAutoWidth = rCopy.bAutoWidth; 7458 bLastBoxInChain = rCopy.bLastBoxInChain; 7459 bHasUDefProp = rCopy.bHasUDefProp; 7460 bVFlip = rCopy.bVFlip; 7461 bHFlip = rCopy.bHFlip; 7462 nClientAnchorLen = rCopy.nClientAnchorLen; 7463 if( rCopy.nClientAnchorLen ) 7464 { 7465 pClientAnchorBuffer = new char[ nClientAnchorLen ]; 7466 memcpy( pClientAnchorBuffer, 7467 rCopy.pClientAnchorBuffer, 7468 nClientAnchorLen ); 7469 } 7470 else 7471 pClientAnchorBuffer = 0; 7472 7473 nClientDataLen = rCopy.nClientDataLen; 7474 if( rCopy.nClientDataLen ) 7475 { 7476 pClientDataBuffer = new char[ nClientDataLen ]; 7477 memcpy( pClientDataBuffer, 7478 rCopy.pClientDataBuffer, 7479 nClientDataLen ); 7480 } 7481 else 7482 pClientDataBuffer = 0; 7483 7484 if (rCopy.pWrapPolygon) 7485 pWrapPolygon = new Polygon(*rCopy.pWrapPolygon); 7486 else 7487 pWrapPolygon = 0; 7488 } 7489 7490 SvxMSDffImportRec::~SvxMSDffImportRec() 7491 { 7492 if (pClientAnchorBuffer) 7493 delete[] pClientAnchorBuffer; 7494 if (pClientDataBuffer) 7495 delete[] pClientDataBuffer; 7496 if (pWrapPolygon) 7497 delete pWrapPolygon; 7498 } 7499 7500 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 7501 7502 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape ) 7503 { 7504 maShapeIdContainer[nShapeId] = pShape; 7505 } 7506 7507 void SvxMSDffManager::removeShapeId( SdrObject* pShape ) 7508 { 7509 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() ); 7510 const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() ); 7511 while( aIter != aEnd ) 7512 { 7513 if( (*aIter).second == pShape ) 7514 { 7515 maShapeIdContainer.erase( aIter ); 7516 break; 7517 } 7518 aIter++; 7519 } 7520 } 7521 7522 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId ) 7523 { 7524 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) ); 7525 return aIter != maShapeIdContainer.end() ? (*aIter).second : 0; 7526 } 7527