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