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