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