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