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