1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <tools/vcompat.hxx> 32 #include <tools/urlobj.hxx> 33 #include <tools/debug.hxx> 34 #include <tools/stream.hxx> 35 36 #include <ucbhelper/content.hxx> 37 38 #include <unotools/ucbstreamhelper.hxx> 39 #include <unotools/tempfile.hxx> 40 41 #include <vcl/outdev.hxx> 42 #include <vcl/virdev.hxx> 43 #include <vcl/gfxlink.hxx> 44 #include <vcl/cvtgrf.hxx> 45 #include <vcl/salbtype.hxx> 46 #include <vcl/graph.hxx> 47 #include <vcl/metaact.hxx> 48 49 #include <impgraph.hxx> 50 51 #include <com/sun/star/ucb/CommandAbortedException.hpp> 52 53 // ----------- 54 // - Defines - 55 // ----------- 56 57 #define GRAPHIC_MAXPARTLEN 256000L 58 #define GRAPHIC_MTFTOBMP_MAXEXT 2048 59 #define GRAPHIC_STREAMBUFSIZE 8192UL 60 61 #define SYS_WINMETAFILE 0x00000003L 62 #define SYS_WNTMETAFILE 0x00000004L 63 #define SYS_OS2METAFILE 0x00000005L 64 #define SYS_MACMETAFILE 0x00000006L 65 66 #define GRAPHIC_FORMAT_50 static_cast<sal_uInt32>(COMPAT_FORMAT( 'G', 'R', 'F', '5' )) 67 #define NATIVE_FORMAT_50 static_cast<sal_uInt32>(COMPAT_FORMAT( 'N', 'A', 'T', '5' )) 68 69 // --------------- 70 // - ImpSwapFile - 71 // --------------- 72 73 struct ImpSwapFile 74 { 75 INetURLObject aSwapURL; 76 sal_uLong nRefCount; 77 }; 78 79 // ----------------- 80 // - Graphicreader - 81 // ----------------- 82 83 class ReaderData 84 { 85 public: 86 Size maPreviewSize; 87 }; 88 89 GraphicReader::~GraphicReader() 90 { 91 delete mpReaderData; 92 } 93 94 // ------------------------------------------------------------------------ 95 96 sal_Bool GraphicReader::IsPreviewModeEnabled() const 97 { 98 if( !mpReaderData ) 99 return sal_False; 100 if( mpReaderData->maPreviewSize.Width() ) 101 return sal_True; 102 if( mpReaderData->maPreviewSize.Height() ) 103 return sal_True; 104 return sal_False; 105 } 106 107 // ------------------------------------------------------------------------ 108 109 void GraphicReader::DisablePreviewMode() 110 { 111 if( mpReaderData ) 112 mpReaderData->maPreviewSize = Size( 0, 0 ); 113 } 114 115 // ------------------------------------------------------------------------ 116 117 void GraphicReader::SetPreviewSize( const Size& rSize ) 118 { 119 if( !mpReaderData ) 120 mpReaderData = new ReaderData; 121 mpReaderData->maPreviewSize = rSize; 122 } 123 124 // ------------------------------------------------------------------------ 125 126 Size GraphicReader::GetPreviewSize() const 127 { 128 Size aSize( 0, 0 ); 129 if( mpReaderData ) 130 aSize = mpReaderData->maPreviewSize; 131 return aSize; 132 } 133 134 // -------------- 135 // - ImpGraphic - 136 // -------------- 137 138 ImpGraphic::ImpGraphic() : 139 mpAnimation ( NULL ), 140 mpContext ( NULL ), 141 mpSwapFile ( NULL ), 142 mpGfxLink ( NULL ), 143 meType ( GRAPHIC_NONE ), 144 mnDocFilePos ( 0UL ), 145 mnSizeBytes ( 0UL ), 146 mnRefCount ( 1UL ), 147 mbSwapOut ( sal_False ), 148 mbSwapUnderway ( sal_False ) 149 { 150 } 151 152 // ------------------------------------------------------------------------ 153 154 ImpGraphic::ImpGraphic( const ImpGraphic& rImpGraphic ) : 155 maMetaFile ( rImpGraphic.maMetaFile ), 156 maEx ( rImpGraphic.maEx ), 157 mpContext ( NULL ), 158 mpSwapFile ( rImpGraphic.mpSwapFile ), 159 meType ( rImpGraphic.meType ), 160 maDocFileURLStr ( rImpGraphic.maDocFileURLStr ), 161 mnDocFilePos ( rImpGraphic.mnDocFilePos ), 162 mnSizeBytes ( rImpGraphic.mnSizeBytes ), 163 mnRefCount ( 1UL ), 164 mbSwapOut ( rImpGraphic.mbSwapOut ), 165 mbSwapUnderway ( sal_False ) 166 { 167 if( mpSwapFile ) 168 mpSwapFile->nRefCount++; 169 170 if( rImpGraphic.mpGfxLink ) 171 mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink ); 172 else 173 mpGfxLink = NULL; 174 175 if( rImpGraphic.mpAnimation ) 176 { 177 mpAnimation = new Animation( *rImpGraphic.mpAnimation ); 178 maEx = mpAnimation->GetBitmapEx(); 179 } 180 else 181 mpAnimation = NULL; 182 } 183 184 // ------------------------------------------------------------------------ 185 186 ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) : 187 maEx ( rBitmap ), 188 mpAnimation ( NULL ), 189 mpContext ( NULL ), 190 mpSwapFile ( NULL ), 191 mpGfxLink ( NULL ), 192 meType ( !rBitmap ? GRAPHIC_NONE : GRAPHIC_BITMAP ), 193 mnDocFilePos ( 0UL ), 194 mnSizeBytes ( 0UL ), 195 mnRefCount ( 1UL ), 196 mbSwapOut ( sal_False ), 197 mbSwapUnderway ( sal_False ) 198 { 199 } 200 201 // ------------------------------------------------------------------------ 202 203 ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) : 204 maEx ( rBitmapEx ), 205 mpAnimation ( NULL ), 206 mpContext ( NULL ), 207 mpSwapFile ( NULL ), 208 mpGfxLink ( NULL ), 209 meType ( !rBitmapEx ? GRAPHIC_NONE : GRAPHIC_BITMAP ), 210 mnDocFilePos ( 0UL ), 211 mnSizeBytes ( 0UL ), 212 mnRefCount ( 1UL ), 213 mbSwapOut ( sal_False ), 214 mbSwapUnderway ( sal_False ) 215 { 216 } 217 218 // ------------------------------------------------------------------------ 219 220 ImpGraphic::ImpGraphic( const Animation& rAnimation ) : 221 maEx ( rAnimation.GetBitmapEx() ), 222 mpAnimation ( new Animation( rAnimation ) ), 223 mpContext ( NULL ), 224 mpSwapFile ( NULL ), 225 mpGfxLink ( NULL ), 226 meType ( GRAPHIC_BITMAP ), 227 mnDocFilePos ( 0UL ), 228 mnSizeBytes ( 0UL ), 229 mnRefCount ( 1UL ), 230 mbSwapOut ( sal_False ), 231 mbSwapUnderway ( sal_False ) 232 { 233 } 234 235 // ------------------------------------------------------------------------ 236 237 ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) : 238 maMetaFile ( rMtf ), 239 mpAnimation ( NULL ), 240 mpContext ( NULL ), 241 mpSwapFile ( NULL ), 242 mpGfxLink ( NULL ), 243 meType ( GRAPHIC_GDIMETAFILE ), 244 mnDocFilePos ( 0UL ), 245 mnSizeBytes ( 0UL ), 246 mnRefCount ( 1UL ), 247 mbSwapOut ( sal_False ), 248 mbSwapUnderway ( sal_False ) 249 { 250 } 251 252 // ------------------------------------------------------------------------ 253 254 ImpGraphic::~ImpGraphic() 255 { 256 ImplClear(); 257 258 if( (sal_uLong) mpContext > 1UL ) 259 delete mpContext; 260 } 261 262 // ------------------------------------------------------------------------ 263 264 ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic ) 265 { 266 if( &rImpGraphic != this ) 267 { 268 if( !mbSwapUnderway ) 269 ImplClear(); 270 271 maMetaFile = rImpGraphic.maMetaFile; 272 meType = rImpGraphic.meType; 273 mnSizeBytes = rImpGraphic.mnSizeBytes; 274 275 delete mpAnimation; 276 277 if ( rImpGraphic.mpAnimation ) 278 { 279 mpAnimation = new Animation( *rImpGraphic.mpAnimation ); 280 maEx = mpAnimation->GetBitmapEx(); 281 } 282 else 283 { 284 mpAnimation = NULL; 285 maEx = rImpGraphic.maEx; 286 } 287 288 if( !mbSwapUnderway ) 289 { 290 maDocFileURLStr = rImpGraphic.maDocFileURLStr; 291 mnDocFilePos = rImpGraphic.mnDocFilePos; 292 mbSwapOut = rImpGraphic.mbSwapOut; 293 mpSwapFile = rImpGraphic.mpSwapFile; 294 295 if( mpSwapFile ) 296 mpSwapFile->nRefCount++; 297 } 298 299 delete mpGfxLink; 300 301 if( rImpGraphic.mpGfxLink ) 302 mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink ); 303 else 304 mpGfxLink = NULL; 305 } 306 307 return *this; 308 } 309 310 // ------------------------------------------------------------------------ 311 312 sal_Bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const 313 { 314 sal_Bool bRet = sal_False; 315 316 if( this == &rImpGraphic ) 317 bRet = sal_True; 318 else if( !ImplIsSwapOut() && ( rImpGraphic.meType == meType ) ) 319 { 320 switch( meType ) 321 { 322 case( GRAPHIC_NONE ): 323 bRet = sal_True; 324 break; 325 326 case( GRAPHIC_GDIMETAFILE ): 327 { 328 if( rImpGraphic.maMetaFile == maMetaFile ) 329 bRet = sal_True; 330 } 331 break; 332 333 case( GRAPHIC_BITMAP ): 334 { 335 if( mpAnimation ) 336 { 337 if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) ) 338 bRet = sal_True; 339 } 340 else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maEx == maEx ) ) 341 bRet = sal_True; 342 } 343 break; 344 345 default: 346 break; 347 } 348 } 349 350 return bRet; 351 } 352 353 // ------------------------------------------------------------------------ 354 355 void ImpGraphic::ImplClearGraphics( sal_Bool bCreateSwapInfo ) 356 { 357 if( bCreateSwapInfo && !ImplIsSwapOut() ) 358 { 359 maSwapInfo.maPrefMapMode = ImplGetPrefMapMode(); 360 maSwapInfo.maPrefSize = ImplGetPrefSize(); 361 } 362 363 maEx.Clear(); 364 maMetaFile.Clear(); 365 366 if( mpAnimation ) 367 { 368 mpAnimation->Clear(); 369 delete mpAnimation; 370 mpAnimation = NULL; 371 } 372 373 if( mpGfxLink ) 374 { 375 delete mpGfxLink; 376 mpGfxLink = NULL; 377 } 378 } 379 380 // ------------------------------------------------------------------------ 381 382 void ImpGraphic::ImplClear() 383 { 384 if( mpSwapFile ) 385 { 386 if( mpSwapFile->nRefCount > 1 ) 387 mpSwapFile->nRefCount--; 388 else 389 { 390 try 391 { 392 ::ucbhelper::Content aCnt( mpSwapFile->aSwapURL.GetMainURL( INetURLObject::NO_DECODE ), 393 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); 394 395 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), 396 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); 397 } 398 catch( const ::com::sun::star::ucb::ContentCreationException& ) 399 { 400 } 401 catch( const ::com::sun::star::uno::RuntimeException& ) 402 { 403 } 404 catch( const ::com::sun::star::ucb::CommandAbortedException& ) 405 { 406 } 407 catch( const ::com::sun::star::uno::Exception& ) 408 { 409 } 410 411 delete mpSwapFile; 412 } 413 414 mpSwapFile = NULL; 415 } 416 417 mbSwapOut = sal_False; 418 mnDocFilePos = 0UL; 419 maDocFileURLStr.Erase(); 420 421 // cleanup 422 ImplClearGraphics( sal_False ); 423 meType = GRAPHIC_NONE; 424 mnSizeBytes = 0; 425 } 426 427 // ------------------------------------------------------------------------ 428 429 GraphicType ImpGraphic::ImplGetType() const 430 { 431 return meType; 432 } 433 434 // ------------------------------------------------------------------------ 435 436 void ImpGraphic::ImplSetDefaultType() 437 { 438 ImplClear(); 439 meType = GRAPHIC_DEFAULT; 440 } 441 442 // ------------------------------------------------------------------------ 443 444 sal_Bool ImpGraphic::ImplIsSupportedGraphic() const 445 { 446 return( meType != GRAPHIC_NONE ); 447 } 448 449 // ------------------------------------------------------------------------ 450 451 sal_Bool ImpGraphic::ImplIsTransparent() const 452 { 453 sal_Bool bRet; 454 455 if( meType == GRAPHIC_BITMAP ) 456 bRet = ( mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent() ); 457 else 458 bRet = sal_True; 459 460 return bRet; 461 } 462 463 // ------------------------------------------------------------------------ 464 465 sal_Bool ImpGraphic::ImplIsAlpha() const 466 { 467 sal_Bool bRet; 468 469 if( meType == GRAPHIC_BITMAP ) 470 bRet = ( NULL == mpAnimation ) && maEx.IsAlpha(); 471 else 472 bRet = sal_False; 473 474 return bRet; 475 } 476 477 // ------------------------------------------------------------------------ 478 479 sal_Bool ImpGraphic::ImplIsAnimated() const 480 { 481 return( mpAnimation != NULL ); 482 } 483 484 // ------------------------------------------------------------------------ 485 486 sal_Bool ImpGraphic::ImplIsEPS() const 487 { 488 return( ( meType == GRAPHIC_GDIMETAFILE ) && 489 ( maMetaFile.GetActionCount() > 0 ) && 490 ( maMetaFile.GetAction( 0 )->GetType() == META_EPS_ACTION ) ); 491 } 492 493 // ------------------------------------------------------------------------ 494 495 sal_Bool ImpGraphic::ImplIsRenderGraphic() const 496 { 497 return( ( GRAPHIC_GDIMETAFILE == meType ) && 498 ( 1 == maMetaFile.GetActionCount() ) && 499 ( META_RENDERGRAPHIC_ACTION == maMetaFile.GetAction( 0 )->GetType() ) ); 500 } 501 502 // ------------------------------------------------------------------------ 503 504 sal_Bool ImpGraphic::ImplHasRenderGraphic() const 505 { 506 sal_Bool bRet = sal_False; 507 508 if( GRAPHIC_GDIMETAFILE == meType ) 509 { 510 GDIMetaFile& rMtf = const_cast< ImpGraphic* >( this )->maMetaFile; 511 512 for( MetaAction* pAct = rMtf.FirstAction(); pAct && !bRet; pAct = rMtf.NextAction() ) 513 { 514 if( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) 515 { 516 bRet = sal_True; 517 } 518 } 519 520 rMtf.WindStart(); 521 } 522 523 return( bRet ); 524 } 525 526 // ------------------------------------------------------------------------ 527 528 Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const 529 { 530 Bitmap aRetBmp; 531 532 if( meType == GRAPHIC_BITMAP ) 533 { 534 const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx ); 535 const Color aReplaceColor( COL_WHITE ); 536 537 aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor ); 538 539 if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) 540 aRetBmp.Scale(rParameters.getSizePixel()); 541 } 542 else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() ) 543 { 544 // use corner points of graphic to determine the pixel 545 // extent of the graphic (rounding errors are possible else) 546 VirtualDevice aVDev; 547 const Point aNullPt; 548 const Point aTLPix( aVDev.LogicToPixel( aNullPt, maMetaFile.GetPrefMapMode() ) ); 549 const Point aBRPix( aVDev.LogicToPixel( Point( maMetaFile.GetPrefSize().Width() - 1, maMetaFile.GetPrefSize().Height() - 1 ), maMetaFile.GetPrefMapMode() ) ); 550 Size aDrawSize( aVDev.LogicToPixel( maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode() ) ); 551 Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 ); 552 553 if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height()) 554 { 555 aDrawSize.Width() = FRound((double)rParameters.getSizePixel().Width() * 556 (double)aDrawSize.Width() / (double)aSizePix.Width()); 557 aDrawSize.Height() = FRound((double)rParameters.getSizePixel().Height() * 558 (double)aDrawSize.Height() / (double)aSizePix.Height()); 559 560 aSizePix = rParameters.getSizePixel(); 561 } 562 563 if( aSizePix.Width() && aSizePix.Height() && !rParameters.getUnlimitedSize() 564 && (aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT)) 565 { 566 const Size aOldSizePix( aSizePix ); 567 double fWH = (double) aSizePix.Width() / aSizePix.Height(); 568 569 if( fWH <= 1.0 ) 570 aSizePix.Width() = FRound( GRAPHIC_MTFTOBMP_MAXEXT * fWH ), aSizePix.Height() = GRAPHIC_MTFTOBMP_MAXEXT; 571 else 572 aSizePix.Width() = GRAPHIC_MTFTOBMP_MAXEXT, aSizePix.Height() = FRound( GRAPHIC_MTFTOBMP_MAXEXT / fWH ); 573 574 aDrawSize.Width() = FRound( ( (double) aDrawSize.Width() * aSizePix.Width() ) / aOldSizePix.Width() ); 575 aDrawSize.Height() = FRound( ( (double) aDrawSize.Height() * aSizePix.Height() ) / aOldSizePix.Height() ); 576 } 577 578 if( aVDev.SetOutputSizePixel( aSizePix ) ) 579 { 580 if(rParameters.getAntiAliase()) 581 { 582 aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); 583 } 584 585 if(rParameters.getSnapHorVerLines()) 586 { 587 aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_PIXELSNAPHAIRLINE); 588 } 589 590 ImplDraw( &aVDev, aNullPt, aDrawSize ); 591 aRetBmp = aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ); 592 } 593 } 594 595 if( !!aRetBmp ) 596 { 597 aRetBmp.SetPrefMapMode( ImplGetPrefMapMode() ); 598 aRetBmp.SetPrefSize( ImplGetPrefSize() ); 599 } 600 601 return aRetBmp; 602 } 603 604 // ------------------------------------------------------------------------ 605 606 BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const 607 { 608 BitmapEx aRetBmpEx; 609 610 if( meType == GRAPHIC_BITMAP ) 611 { 612 aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx ); 613 614 if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) 615 aRetBmpEx.Scale(rParameters.getSizePixel()); 616 } 617 else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() ) 618 { 619 const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) ); 620 aRetBmpEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters)); 621 } 622 623 return aRetBmpEx; 624 } 625 626 // ------------------------------------------------------------------------ 627 628 Animation ImpGraphic::ImplGetAnimation() const 629 { 630 Animation aAnimation; 631 632 if( mpAnimation ) 633 aAnimation = *mpAnimation; 634 635 return aAnimation; 636 } 637 638 // ------------------------------------------------------------------------ 639 640 ::vcl::RenderGraphic ImpGraphic::ImplGetRenderGraphic() const 641 { 642 ::vcl::RenderGraphic aRet; 643 644 if( ImplIsRenderGraphic() ) 645 aRet = static_cast< MetaRenderGraphicAction* >( maMetaFile.GetAction( 0 ) )->GetRenderGraphic(); 646 647 return( aRet ); 648 } 649 650 // ------------------------------------------------------------------------ 651 652 const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const 653 { 654 return maMetaFile; 655 } 656 657 // ------------------------------------------------------------------------ 658 659 Size ImpGraphic::ImplGetPrefSize() const 660 { 661 Size aSize; 662 663 if( ImplIsSwapOut() ) 664 aSize = maSwapInfo.maPrefSize; 665 else 666 { 667 switch( meType ) 668 { 669 case( GRAPHIC_NONE ): 670 case( GRAPHIC_DEFAULT ): 671 break; 672 673 case( GRAPHIC_BITMAP ): 674 { 675 aSize = maEx.GetPrefSize(); 676 677 if( !aSize.Width() || !aSize.Height() ) 678 aSize = maEx.GetSizePixel(); 679 } 680 break; 681 682 default: 683 { 684 if( ImplIsSupportedGraphic() ) 685 aSize = maMetaFile.GetPrefSize(); 686 } 687 break; 688 } 689 } 690 691 return aSize; 692 } 693 694 // ------------------------------------------------------------------------ 695 696 void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize ) 697 { 698 switch( meType ) 699 { 700 case( GRAPHIC_NONE ): 701 case( GRAPHIC_DEFAULT ): 702 break; 703 704 case( GRAPHIC_BITMAP ): 705 // #108077# Push through pref size to animation object, 706 // will be lost on copy otherwise 707 if( ImplIsAnimated() ) 708 const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize ); 709 710 maEx.SetPrefSize( rPrefSize ); 711 break; 712 713 default: 714 { 715 if( ImplIsSupportedGraphic() ) 716 maMetaFile.SetPrefSize( rPrefSize ); 717 } 718 break; 719 } 720 } 721 722 // ------------------------------------------------------------------------ 723 724 MapMode ImpGraphic::ImplGetPrefMapMode() const 725 { 726 MapMode aMapMode; 727 728 if( ImplIsSwapOut() ) 729 aMapMode = maSwapInfo.maPrefMapMode; 730 else 731 { 732 switch( meType ) 733 { 734 case( GRAPHIC_NONE ): 735 case( GRAPHIC_DEFAULT ): 736 break; 737 738 case( GRAPHIC_BITMAP ): 739 { 740 const Size aSize( maEx.GetPrefSize() ); 741 742 if ( aSize.Width() && aSize.Height() ) 743 aMapMode = maEx.GetPrefMapMode(); 744 } 745 break; 746 747 default: 748 { 749 if( ImplIsSupportedGraphic() ) 750 return maMetaFile.GetPrefMapMode(); 751 } 752 break; 753 } 754 } 755 756 return aMapMode; 757 } 758 759 // ------------------------------------------------------------------------ 760 761 void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode ) 762 { 763 switch( meType ) 764 { 765 case( GRAPHIC_NONE ): 766 case( GRAPHIC_DEFAULT ): 767 break; 768 769 case( GRAPHIC_BITMAP ): 770 // #108077# Push through pref mapmode to animation object, 771 // will be lost on copy otherwise 772 if( ImplIsAnimated() ) 773 const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefMapMode( rPrefMapMode ); 774 775 maEx.SetPrefMapMode( rPrefMapMode ); 776 break; 777 778 default: 779 { 780 if( ImplIsSupportedGraphic() ) 781 maMetaFile.SetPrefMapMode( rPrefMapMode ); 782 } 783 break; 784 } 785 } 786 787 // ------------------------------------------------------------------------ 788 789 sal_uLong ImpGraphic::ImplGetSizeBytes() const 790 { 791 if( 0 == mnSizeBytes ) 792 { 793 if( meType == GRAPHIC_BITMAP ) 794 { 795 mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maEx.GetSizeBytes(); 796 } 797 else if( meType == GRAPHIC_GDIMETAFILE ) 798 { 799 mnSizeBytes = maMetaFile.GetSizeBytes(); 800 } 801 } 802 803 return( mnSizeBytes ); 804 } 805 806 // ------------------------------------------------------------------------ 807 808 void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const 809 { 810 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() ) 811 { 812 switch( meType ) 813 { 814 case( GRAPHIC_DEFAULT ): 815 break; 816 817 case( GRAPHIC_BITMAP ): 818 { 819 if ( mpAnimation ) 820 mpAnimation->Draw( pOutDev, rDestPt ); 821 else 822 maEx.Draw( pOutDev, rDestPt ); 823 } 824 break; 825 826 default: 827 ImplDraw( pOutDev, rDestPt, maMetaFile.GetPrefSize() ); 828 break; 829 } 830 } 831 } 832 833 // ------------------------------------------------------------------------ 834 835 void ImpGraphic::ImplDraw( OutputDevice* pOutDev, 836 const Point& rDestPt, const Size& rDestSize ) const 837 { 838 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() ) 839 { 840 switch( meType ) 841 { 842 case( GRAPHIC_DEFAULT ): 843 break; 844 845 case( GRAPHIC_BITMAP ): 846 { 847 if( mpAnimation ) 848 mpAnimation->Draw( pOutDev, rDestPt, rDestSize ); 849 else 850 maEx.Draw( pOutDev, rDestPt, rDestSize ); 851 } 852 break; 853 854 default: 855 { 856 ( (ImpGraphic*) this )->maMetaFile.WindStart(); 857 ( (ImpGraphic*) this )->maMetaFile.Play( pOutDev, rDestPt, rDestSize ); 858 ( (ImpGraphic*) this )->maMetaFile.WindStart(); 859 } 860 break; 861 } 862 } 863 } 864 865 // ------------------------------------------------------------------------ 866 867 void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, 868 const Point& rDestPt, 869 long nExtraData, 870 OutputDevice* pFirstFrameOutDev ) 871 { 872 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation ) 873 mpAnimation->Start( pOutDev, rDestPt, nExtraData, pFirstFrameOutDev ); 874 } 875 876 // ------------------------------------------------------------------------ 877 878 void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, const Point& rDestPt, 879 const Size& rDestSize, long nExtraData, 880 OutputDevice* pFirstFrameOutDev ) 881 { 882 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation ) 883 mpAnimation->Start( pOutDev, rDestPt, rDestSize, nExtraData, pFirstFrameOutDev ); 884 } 885 886 // ------------------------------------------------------------------------ 887 888 void ImpGraphic::ImplStopAnimation( OutputDevice* pOutDev, long nExtraData ) 889 { 890 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation ) 891 mpAnimation->Stop( pOutDev, nExtraData ); 892 } 893 894 // ------------------------------------------------------------------------ 895 896 void ImpGraphic::ImplSetAnimationNotifyHdl( const Link& rLink ) 897 { 898 if( mpAnimation ) 899 mpAnimation->SetNotifyHdl( rLink ); 900 } 901 902 // ------------------------------------------------------------------------ 903 904 Link ImpGraphic::ImplGetAnimationNotifyHdl() const 905 { 906 Link aLink; 907 908 if( mpAnimation ) 909 aLink = mpAnimation->GetNotifyHdl(); 910 911 return aLink; 912 } 913 914 // ------------------------------------------------------------------------ 915 916 sal_uLong ImpGraphic::ImplGetAnimationLoopCount() const 917 { 918 return( mpAnimation ? mpAnimation->GetLoopCount() : 0UL ); 919 } 920 921 // ------------------------------------------------------------------------ 922 923 void ImpGraphic::ImplResetAnimationLoopCount() 924 { 925 if( mpAnimation ) 926 mpAnimation->ResetLoopCount(); 927 } 928 929 // ------------------------------------------------------------------------ 930 931 List* ImpGraphic::ImplGetAnimationInfoList() const 932 { 933 return( mpAnimation ? mpAnimation->GetAInfoList() : NULL ); 934 } 935 936 // ------------------------------------------------------------------------ 937 938 GraphicReader* ImpGraphic::ImplGetContext() 939 { 940 return mpContext; 941 } 942 943 // ------------------------------------------------------------------------ 944 945 void ImpGraphic::ImplSetContext( GraphicReader* pReader ) 946 { 947 mpContext = pReader; 948 } 949 950 // ------------------------------------------------------------------------ 951 952 void ImpGraphic::ImplSetDocFileName( const String& rName, sal_uLong nFilePos ) 953 { 954 const INetURLObject aURL( rName ); 955 956 DBG_ASSERT( !rName.Len() || ( aURL.GetProtocol() != INET_PROT_NOT_VALID ), "Graphic::SetDocFileName(...): invalid URL" ); 957 958 maDocFileURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE ); 959 mnDocFilePos = nFilePos; 960 } 961 962 // ------------------------------------------------------------------------ 963 964 const String& ImpGraphic::ImplGetDocFileName() const 965 { 966 return maDocFileURLStr; 967 } 968 969 // ------------------------------------------------------------------------ 970 971 sal_uLong ImpGraphic::ImplGetDocFilePos() const 972 { 973 return mnDocFilePos; 974 } 975 976 // ------------------------------------------------------------------------ 977 978 sal_Bool ImpGraphic::ImplReadEmbedded( SvStream& rIStm, sal_Bool bSwap ) 979 { 980 MapMode aMapMode; 981 Size aSize; 982 const sal_uLong nStartPos = rIStm.Tell(); 983 sal_uInt32 nId; 984 sal_uLong nHeaderLen; 985 long nType; 986 long nLen; 987 const sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); 988 sal_Bool bRet = sal_False; 989 990 if( !mbSwapUnderway ) 991 { 992 const String aTempURLStr( maDocFileURLStr ); 993 const sal_uLong nTempPos = mnDocFilePos; 994 995 ImplClear(); 996 997 maDocFileURLStr = aTempURLStr; 998 mnDocFilePos = nTempPos; 999 } 1000 1001 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 1002 rIStm >> nId; 1003 1004 // check version 1005 if( GRAPHIC_FORMAT_50 == nId ) 1006 { 1007 // read new style header 1008 VersionCompat* pCompat = new VersionCompat( rIStm, STREAM_READ ); 1009 1010 rIStm >> nType; 1011 rIStm >> nLen; 1012 rIStm >> aSize; 1013 rIStm >> aMapMode; 1014 1015 delete pCompat; 1016 } 1017 else 1018 { 1019 // read old style header 1020 long nWidth, nHeight; 1021 long nMapMode, nScaleNumX, nScaleDenomX; 1022 long nScaleNumY, nScaleDenomY, nOffsX, nOffsY; 1023 1024 rIStm.SeekRel( -4L ); 1025 1026 rIStm >> nType >> nLen >> nWidth >> nHeight; 1027 rIStm >> nMapMode >> nScaleNumX >> nScaleDenomX >> nScaleNumY; 1028 rIStm >> nScaleDenomY >> nOffsX >> nOffsY; 1029 1030 // swapped 1031 if( nType > 100L ) 1032 { 1033 nType = SWAPLONG( nType ); 1034 nLen = SWAPLONG( nLen ); 1035 nWidth = SWAPLONG( nWidth ); 1036 nHeight = SWAPLONG( nHeight ); 1037 nMapMode = SWAPLONG( nMapMode ); 1038 nScaleNumX = SWAPLONG( nScaleNumX ); 1039 nScaleDenomX = SWAPLONG( nScaleDenomX ); 1040 nScaleNumY = SWAPLONG( nScaleNumY ); 1041 nScaleDenomY = SWAPLONG( nScaleDenomY ); 1042 nOffsX = SWAPLONG( nOffsX ); 1043 nOffsY = SWAPLONG( nOffsY ); 1044 } 1045 1046 aSize = Size( nWidth, nHeight ); 1047 aMapMode = MapMode( (MapUnit) nMapMode, Point( nOffsX, nOffsY ), 1048 Fraction( nScaleNumX, nScaleDenomX ), 1049 Fraction( nScaleNumY, nScaleDenomY ) ); 1050 } 1051 1052 nHeaderLen = rIStm.Tell() - nStartPos; 1053 meType = (GraphicType) nType; 1054 1055 if( meType ) 1056 { 1057 if( meType == GRAPHIC_BITMAP ) 1058 { 1059 maEx.aBitmapSize = aSize; 1060 1061 if( aMapMode != MapMode() ) 1062 { 1063 maEx.SetPrefMapMode( aMapMode ); 1064 maEx.SetPrefSize( aSize ); 1065 } 1066 } 1067 else 1068 { 1069 maMetaFile.SetPrefMapMode( aMapMode ); 1070 maMetaFile.SetPrefSize( aSize ); 1071 } 1072 1073 if( bSwap ) 1074 { 1075 if( maDocFileURLStr.Len() ) 1076 { 1077 rIStm.Seek( nStartPos + nHeaderLen + nLen ); 1078 bRet = mbSwapOut = sal_True; 1079 } 1080 else 1081 { 1082 ::utl::TempFile aTempFile; 1083 const INetURLObject aTmpURL( aTempFile.GetURL() ); 1084 1085 if( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() ) 1086 { 1087 SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); 1088 1089 if( pOStm ) 1090 { 1091 sal_uLong nFullLen = nHeaderLen + nLen; 1092 sal_uLong nPartLen = Min( nFullLen, (sal_uLong) GRAPHIC_MAXPARTLEN ); 1093 sal_uInt8* pBuffer = (sal_uInt8*) rtl_allocateMemory( nPartLen ); 1094 1095 pOStm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 1096 1097 if( pBuffer ) 1098 { 1099 rIStm.Seek( nStartPos ); 1100 1101 while( nFullLen ) 1102 { 1103 rIStm.Read( (char*) pBuffer, nPartLen ); 1104 pOStm->Write( (char*) pBuffer, nPartLen ); 1105 1106 nFullLen -= nPartLen; 1107 1108 if( nFullLen < GRAPHIC_MAXPARTLEN ) 1109 nPartLen = nFullLen; 1110 } 1111 1112 rtl_freeMemory( pBuffer ); 1113 sal_uLong nReadErr = rIStm.GetError(), nWriteErr = pOStm->GetError(); 1114 delete pOStm, pOStm = NULL; 1115 1116 if( !nReadErr && !nWriteErr ) 1117 { 1118 bRet = mbSwapOut = sal_True; 1119 mpSwapFile = new ImpSwapFile; 1120 mpSwapFile->nRefCount = 1; 1121 mpSwapFile->aSwapURL = aTmpURL; 1122 } 1123 else 1124 { 1125 try 1126 { 1127 ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), 1128 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); 1129 1130 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), 1131 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); 1132 } 1133 catch( const ::com::sun::star::ucb::ContentCreationException& ) 1134 { 1135 } 1136 catch( const ::com::sun::star::uno::RuntimeException& ) 1137 { 1138 } 1139 catch( const ::com::sun::star::ucb::CommandAbortedException& ) 1140 { 1141 } 1142 catch( const ::com::sun::star::uno::Exception& ) 1143 { 1144 } 1145 } 1146 } 1147 1148 delete pOStm; 1149 } 1150 } 1151 } 1152 } 1153 else if( meType == GRAPHIC_BITMAP || meType == GRAPHIC_GDIMETAFILE ) 1154 { 1155 rIStm >> *this; 1156 bRet = ( rIStm.GetError() == 0UL ); 1157 } 1158 else if( meType >= SYS_WINMETAFILE && meType <= SYS_MACMETAFILE ) 1159 { 1160 Graphic aSysGraphic; 1161 sal_uLong nCvtType; 1162 1163 switch( sal::static_int_cast<sal_uLong>(meType) ) 1164 { 1165 case( SYS_WINMETAFILE ): 1166 case( SYS_WNTMETAFILE ): nCvtType = CVT_WMF; break; 1167 case( SYS_OS2METAFILE ): nCvtType = CVT_MET; break; 1168 case( SYS_MACMETAFILE ): nCvtType = CVT_PCT; break; 1169 1170 default: 1171 nCvtType = CVT_UNKNOWN; 1172 break; 1173 } 1174 1175 if( nType && GraphicConverter::Import( rIStm, aSysGraphic, nCvtType ) == ERRCODE_NONE ) 1176 { 1177 *this = ImpGraphic( aSysGraphic.GetGDIMetaFile() ); 1178 bRet = ( rIStm.GetError() == 0UL ); 1179 } 1180 else 1181 meType = GRAPHIC_DEFAULT; 1182 } 1183 1184 if( bRet ) 1185 { 1186 ImplSetPrefMapMode( aMapMode ); 1187 ImplSetPrefSize( aSize ); 1188 } 1189 } 1190 else 1191 bRet = sal_True; 1192 1193 rIStm.SetNumberFormatInt( nOldFormat ); 1194 1195 return bRet; 1196 } 1197 1198 // ------------------------------------------------------------------------ 1199 1200 sal_Bool ImpGraphic::ImplWriteEmbedded( SvStream& rOStm ) 1201 { 1202 sal_Bool bRet = sal_False; 1203 1204 if( ( meType != GRAPHIC_NONE ) && ( meType != GRAPHIC_DEFAULT ) && !ImplIsSwapOut() ) 1205 { 1206 const MapMode aMapMode( ImplGetPrefMapMode() ); 1207 const Size aSize( ImplGetPrefSize() ); 1208 const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt(); 1209 sal_uLong nDataFieldPos; 1210 1211 rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 1212 1213 // write correct version ( old style/new style header ) 1214 if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) 1215 { 1216 // write ID for new format (5.0) 1217 rOStm << GRAPHIC_FORMAT_50; 1218 1219 // write new style header 1220 VersionCompat* pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 ); 1221 1222 rOStm << (long) meType; 1223 1224 // data size is updated later 1225 nDataFieldPos = rOStm.Tell(); 1226 rOStm << (long) 0; 1227 1228 rOStm << aSize; 1229 rOStm << aMapMode; 1230 1231 delete pCompat; 1232 } 1233 else 1234 { 1235 // write old style (<=4.0) header 1236 rOStm << (long) meType; 1237 1238 // data size is updated later 1239 nDataFieldPos = rOStm.Tell(); 1240 rOStm << (long) 0; 1241 1242 rOStm << (long) aSize.Width(); 1243 rOStm << (long) aSize.Height(); 1244 rOStm << (long) aMapMode.GetMapUnit(); 1245 rOStm << (long) aMapMode.GetScaleX().GetNumerator(); 1246 rOStm << (long) aMapMode.GetScaleX().GetDenominator(); 1247 rOStm << (long) aMapMode.GetScaleY().GetNumerator(); 1248 rOStm << (long) aMapMode.GetScaleY().GetDenominator(); 1249 rOStm << (long) aMapMode.GetOrigin().X(); 1250 rOStm << (long) aMapMode.GetOrigin().Y(); 1251 } 1252 1253 // write data block 1254 if( !rOStm.GetError() ) 1255 { 1256 const sal_uLong nDataStart = rOStm.Tell(); 1257 1258 if( ImplIsSupportedGraphic() ) 1259 rOStm << *this; 1260 1261 if( !rOStm.GetError() ) 1262 { 1263 const sal_uLong nStmPos2 = rOStm.Tell(); 1264 rOStm.Seek( nDataFieldPos ); 1265 rOStm << (long) ( nStmPos2 - nDataStart ); 1266 rOStm.Seek( nStmPos2 ); 1267 bRet = sal_True; 1268 } 1269 } 1270 1271 rOStm.SetNumberFormatInt( nOldFormat ); 1272 } 1273 1274 return bRet; 1275 } 1276 1277 // ------------------------------------------------------------------------ 1278 1279 sal_Bool ImpGraphic::ImplSwapOut() 1280 { 1281 sal_Bool bRet = sal_False; 1282 1283 if( !ImplIsSwapOut() ) 1284 { 1285 if( !maDocFileURLStr.Len() ) 1286 { 1287 ::utl::TempFile aTempFile; 1288 const INetURLObject aTmpURL( aTempFile.GetURL() ); 1289 1290 if( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() ) 1291 { 1292 SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); 1293 1294 if( pOStm ) 1295 { 1296 pOStm->SetVersion( SOFFICE_FILEFORMAT_50 ); 1297 pOStm->SetCompressMode( COMPRESSMODE_NATIVE ); 1298 1299 if( ( bRet = ImplSwapOut( pOStm ) ) == sal_True ) 1300 { 1301 mpSwapFile = new ImpSwapFile; 1302 mpSwapFile->nRefCount = 1; 1303 mpSwapFile->aSwapURL = aTmpURL; 1304 } 1305 else 1306 { 1307 delete pOStm, pOStm = NULL; 1308 1309 try 1310 { 1311 ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), 1312 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); 1313 1314 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), 1315 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); 1316 } 1317 catch( const ::com::sun::star::ucb::ContentCreationException& ) 1318 { 1319 } 1320 catch( const ::com::sun::star::uno::RuntimeException& ) 1321 { 1322 } 1323 catch( const ::com::sun::star::ucb::CommandAbortedException& ) 1324 { 1325 } 1326 catch( const ::com::sun::star::uno::Exception& ) 1327 { 1328 } 1329 } 1330 1331 delete pOStm; 1332 } 1333 } 1334 } 1335 else 1336 { 1337 ImplClearGraphics( sal_True ); 1338 bRet = mbSwapOut = sal_True; 1339 } 1340 } 1341 1342 return bRet; 1343 } 1344 1345 // ------------------------------------------------------------------------ 1346 1347 sal_Bool ImpGraphic::ImplSwapOut( SvStream* pOStm ) 1348 { 1349 sal_Bool bRet = sal_False; 1350 1351 if( pOStm ) 1352 { 1353 pOStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE ); 1354 1355 if( !pOStm->GetError() && ImplWriteEmbedded( *pOStm ) ) 1356 { 1357 pOStm->Flush(); 1358 1359 if( !pOStm->GetError() ) 1360 { 1361 ImplClearGraphics( sal_True ); 1362 bRet = mbSwapOut = sal_True; 1363 } 1364 } 1365 } 1366 else 1367 { 1368 ImplClearGraphics( sal_True ); 1369 bRet = mbSwapOut = sal_True; 1370 } 1371 1372 return bRet; 1373 } 1374 1375 // ------------------------------------------------------------------------ 1376 1377 sal_Bool ImpGraphic::ImplSwapIn() 1378 { 1379 sal_Bool bRet = sal_False; 1380 1381 if( ImplIsSwapOut() ) 1382 { 1383 String aSwapURL; 1384 1385 if( mpSwapFile ) 1386 aSwapURL = mpSwapFile->aSwapURL.GetMainURL( INetURLObject::NO_DECODE ); 1387 else 1388 aSwapURL = maDocFileURLStr; 1389 1390 if( aSwapURL.Len() ) 1391 { 1392 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aSwapURL, STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); 1393 1394 if( pIStm ) 1395 { 1396 pIStm->SetVersion( SOFFICE_FILEFORMAT_50 ); 1397 pIStm->SetCompressMode( COMPRESSMODE_NATIVE ); 1398 1399 if( !mpSwapFile ) 1400 pIStm->Seek( mnDocFilePos ); 1401 1402 bRet = ImplSwapIn( pIStm ); 1403 delete pIStm; 1404 1405 if( mpSwapFile ) 1406 { 1407 if( mpSwapFile->nRefCount > 1 ) 1408 mpSwapFile->nRefCount--; 1409 else 1410 { 1411 try 1412 { 1413 ::ucbhelper::Content aCnt( aSwapURL, 1414 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); 1415 1416 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), 1417 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); 1418 } 1419 catch( const ::com::sun::star::ucb::ContentCreationException& ) 1420 { 1421 } 1422 catch( const ::com::sun::star::uno::RuntimeException& ) 1423 { 1424 } 1425 catch( const ::com::sun::star::ucb::CommandAbortedException& ) 1426 { 1427 } 1428 catch( const ::com::sun::star::uno::Exception& ) 1429 { 1430 } 1431 1432 delete mpSwapFile; 1433 } 1434 1435 mpSwapFile = NULL; 1436 } 1437 } 1438 } 1439 } 1440 1441 return bRet; 1442 } 1443 1444 // ------------------------------------------------------------------------ 1445 1446 sal_Bool ImpGraphic::ImplSwapIn( SvStream* pIStm ) 1447 { 1448 sal_Bool bRet = sal_False; 1449 1450 if( pIStm ) 1451 { 1452 pIStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE ); 1453 1454 if( !pIStm->GetError() ) 1455 { 1456 mbSwapUnderway = sal_True; 1457 bRet = ImplReadEmbedded( *pIStm ); 1458 mbSwapUnderway = sal_False; 1459 1460 if( !bRet ) 1461 ImplClear(); 1462 else 1463 mbSwapOut = sal_False; 1464 } 1465 } 1466 1467 return bRet; 1468 } 1469 1470 // ------------------------------------------------------------------------ 1471 1472 sal_Bool ImpGraphic::ImplIsSwapOut() const 1473 { 1474 return mbSwapOut; 1475 } 1476 1477 // ------------------------------------------------------------------------ 1478 1479 void ImpGraphic::ImplSetLink( const GfxLink& rGfxLink ) 1480 { 1481 delete mpGfxLink; 1482 mpGfxLink = new GfxLink( rGfxLink ); 1483 1484 if( mpGfxLink->IsNative() ) 1485 mpGfxLink->SwapOut(); 1486 } 1487 1488 // ------------------------------------------------------------------------ 1489 1490 GfxLink ImpGraphic::ImplGetLink() 1491 { 1492 return( mpGfxLink ? *mpGfxLink : GfxLink() ); 1493 } 1494 1495 // ------------------------------------------------------------------------ 1496 1497 sal_Bool ImpGraphic::ImplIsLink() const 1498 { 1499 return ( mpGfxLink != NULL ) ? sal_True : sal_False; 1500 } 1501 1502 // ------------------------------------------------------------------------ 1503 1504 sal_uLong ImpGraphic::ImplGetChecksum() const 1505 { 1506 sal_uLong nRet = 0; 1507 1508 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() ) 1509 { 1510 switch( meType ) 1511 { 1512 case( GRAPHIC_DEFAULT ): 1513 break; 1514 1515 case( GRAPHIC_BITMAP ): 1516 { 1517 if( mpAnimation ) 1518 nRet = mpAnimation->GetChecksum(); 1519 else 1520 nRet = maEx.GetChecksum(); 1521 } 1522 break; 1523 1524 default: 1525 nRet = maMetaFile.GetChecksum(); 1526 break; 1527 } 1528 } 1529 1530 return nRet; 1531 } 1532 1533 // ------------------------------------------------------------------------ 1534 1535 sal_Bool ImpGraphic::ImplExportNative( SvStream& rOStm ) const 1536 { 1537 sal_Bool bResult = sal_False; 1538 1539 if( !rOStm.GetError() ) 1540 { 1541 if( !ImplIsSwapOut() ) 1542 { 1543 if( mpGfxLink && mpGfxLink->IsNative() ) 1544 bResult = mpGfxLink->ExportNative( rOStm ); 1545 else 1546 { 1547 rOStm << *this; 1548 bResult = ( rOStm.GetError() == ERRCODE_NONE ); 1549 } 1550 } 1551 else 1552 rOStm.SetError( SVSTREAM_GENERALERROR ); 1553 } 1554 1555 return bResult; 1556 } 1557 1558 // ------------------------------------------------------------------------ 1559 1560 SvStream& operator>>( SvStream& rIStm, ImpGraphic& rImpGraphic ) 1561 { 1562 if( !rIStm.GetError() ) 1563 { 1564 const sal_uLong nStmPos1 = rIStm.Tell(); 1565 sal_uInt32 nTmp; 1566 1567 if ( !rImpGraphic.mbSwapUnderway ) 1568 rImpGraphic.ImplClear(); 1569 1570 // read Id 1571 rIStm >> nTmp; 1572 1573 // if there is no more data, avoid further expensive 1574 // reading which will create VDevs and other stuff, just to 1575 // read nothing. CAUTION: Eof is only true AFTER reading another 1576 // byte, a speciality of SvMemoryStream (!) 1577 if(!rIStm.GetError() && !rIStm.IsEof()) 1578 { 1579 if( NATIVE_FORMAT_50 == nTmp ) 1580 { 1581 Graphic aGraphic; 1582 GfxLink aLink; 1583 VersionCompat* pCompat; 1584 1585 // read compat info 1586 pCompat = new VersionCompat( rIStm, STREAM_READ ); 1587 delete pCompat; 1588 1589 rIStm >> aLink; 1590 1591 // set dummy link to avoid creation of additional link after filtering; 1592 // we set a default link to avoid unnecessary swapping of native data 1593 aGraphic.SetLink( GfxLink() ); 1594 1595 if( !rIStm.GetError() && aLink.LoadNative( aGraphic ) ) 1596 { 1597 // set link only, if no other link was set 1598 const sal_Bool bSetLink = ( rImpGraphic.mpGfxLink == NULL ); 1599 1600 // assign graphic 1601 rImpGraphic = *aGraphic.ImplGetImpGraphic(); 1602 1603 if( aLink.IsPrefMapModeValid() ) 1604 rImpGraphic.ImplSetPrefMapMode( aLink.GetPrefMapMode() ); 1605 1606 if( aLink.IsPrefSizeValid() ) 1607 rImpGraphic.ImplSetPrefSize( aLink.GetPrefSize() ); 1608 1609 if( bSetLink ) 1610 rImpGraphic.ImplSetLink( aLink ); 1611 } 1612 else 1613 { 1614 rIStm.Seek( nStmPos1 ); 1615 rIStm.SetError( ERRCODE_IO_WRONGFORMAT ); 1616 } 1617 } 1618 else 1619 { 1620 BitmapEx aBmpEx; 1621 const sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); 1622 1623 rIStm.SeekRel( -4 ); 1624 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 1625 rIStm >> aBmpEx; 1626 1627 if( !rIStm.GetError() ) 1628 { 1629 sal_uInt32 nMagic1(0), nMagic2(0); 1630 sal_uLong nActPos = rIStm.Tell(); 1631 1632 rIStm >> nMagic1 >> nMagic2; 1633 rIStm.Seek( nActPos ); 1634 1635 rImpGraphic = ImpGraphic( aBmpEx ); 1636 1637 if( !rIStm.GetError() && ( 0x5344414e == nMagic1 ) && ( 0x494d4931 == nMagic2 ) ) 1638 { 1639 delete rImpGraphic.mpAnimation; 1640 rImpGraphic.mpAnimation = new Animation; 1641 rIStm >> *rImpGraphic.mpAnimation; 1642 1643 // #108077# manually set loaded BmpEx to Animation 1644 // (which skips loading its BmpEx if already done) 1645 rImpGraphic.mpAnimation->SetBitmapEx(aBmpEx); 1646 } 1647 else 1648 rIStm.ResetError(); 1649 } 1650 else 1651 { 1652 GDIMetaFile aMtf; 1653 1654 rIStm.Seek( nStmPos1 ); 1655 rIStm.ResetError(); 1656 rIStm >> aMtf; 1657 1658 if( !rIStm.GetError() ) 1659 rImpGraphic = aMtf; 1660 else 1661 rIStm.Seek( nStmPos1 ); 1662 } 1663 1664 rIStm.SetNumberFormatInt( nOldFormat ); 1665 } 1666 } 1667 } 1668 1669 return rIStm; 1670 } 1671 1672 // ------------------------------------------------------------------------ 1673 1674 SvStream& operator<<( SvStream& rOStm, const ImpGraphic& rImpGraphic ) 1675 { 1676 if( !rOStm.GetError() ) 1677 { 1678 if( !rImpGraphic.ImplIsSwapOut() ) 1679 { 1680 if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) && 1681 ( rOStm.GetCompressMode() & COMPRESSMODE_NATIVE ) && 1682 rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() ) 1683 { 1684 VersionCompat* pCompat; 1685 1686 // native format 1687 rOStm << NATIVE_FORMAT_50; 1688 1689 // write compat info 1690 pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 ); 1691 delete pCompat; 1692 1693 rImpGraphic.mpGfxLink->SetPrefMapMode( rImpGraphic.ImplGetPrefMapMode() ); 1694 rImpGraphic.mpGfxLink->SetPrefSize( rImpGraphic.ImplGetPrefSize() ); 1695 rOStm << *rImpGraphic.mpGfxLink; 1696 } 1697 else 1698 { 1699 // own format 1700 const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt(); 1701 rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 1702 1703 switch( rImpGraphic.ImplGetType() ) 1704 { 1705 case( GRAPHIC_NONE ): 1706 case( GRAPHIC_DEFAULT ): 1707 break; 1708 1709 case GRAPHIC_BITMAP: 1710 { 1711 if ( rImpGraphic.ImplIsAnimated() ) 1712 rOStm << *rImpGraphic.mpAnimation; 1713 else 1714 rOStm << rImpGraphic.maEx; 1715 } 1716 break; 1717 1718 default: 1719 { 1720 if( rImpGraphic.ImplIsSupportedGraphic() ) 1721 rOStm << rImpGraphic.maMetaFile; 1722 } 1723 break; 1724 } 1725 1726 rOStm.SetNumberFormatInt( nOldFormat ); 1727 } 1728 } 1729 else 1730 rOStm.SetError( SVSTREAM_GENERALERROR ); 1731 } 1732 1733 return rOStm; 1734 } 1735