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_svtools.hxx" 30 31 #define ENABLE_BYTESTRING_STREAM_OPERATORS 32 33 #include <algorithm> 34 35 #include <tools/vcompat.hxx> 36 #include <unotools/ucbstreamhelper.hxx> 37 #include <unotools/localfilehelper.hxx> 38 #include <unotools/tempfile.hxx> 39 #include <vcl/svapp.hxx> 40 #include <vcl/cvtgrf.hxx> 41 #include <vcl/metaact.hxx> 42 #include <vcl/virdev.hxx> 43 #include <vcl/salbtype.hxx> 44 #include <unotools/cacheoptions.hxx> 45 #include <svtools/grfmgr.hxx> 46 47 // --> OD 2010-01-04 #i105243# 48 #include <vcl/pdfextoutdevdata.hxx> 49 // <-- 50 51 // ----------- 52 // - Defines - 53 // ----------- 54 55 #define WATERMARK_LUM_OFFSET 50 56 #define WATERMARK_CON_OFFSET -70 57 58 // ----------- 59 // - statics - 60 // ----------- 61 62 GraphicManager* GraphicObject::mpGlobalMgr = NULL; 63 64 // --------------------- 65 // - GrfDirectCacheObj - 66 // --------------------- 67 68 struct GrfSimpleCacheObj 69 { 70 Graphic maGraphic; 71 GraphicAttr maAttr; 72 73 GrfSimpleCacheObj( const Graphic& rGraphic, const GraphicAttr& rAttr ) : 74 maGraphic( rGraphic ), maAttr( rAttr ) {} 75 }; 76 77 // ----------------- 78 // - GraphicObject - 79 // ----------------- 80 81 TYPEINIT1_AUTOFACTORY( GraphicObject, SvDataCopyStream ); 82 83 // ----------------------------------------------------------------------------- 84 85 GraphicObject::GraphicObject( const GraphicManager* pMgr ) : 86 mpLink ( NULL ), 87 mpUserData ( NULL ) 88 { 89 ImplConstruct(); 90 ImplAssignGraphicData(); 91 ImplSetGraphicManager( pMgr ); 92 } 93 94 // ----------------------------------------------------------------------------- 95 96 GraphicObject::GraphicObject( const Graphic& rGraphic, const GraphicManager* pMgr ) : 97 maGraphic ( rGraphic ), 98 mpLink ( NULL ), 99 mpUserData ( NULL ) 100 { 101 ImplConstruct(); 102 ImplAssignGraphicData(); 103 ImplSetGraphicManager( pMgr ); 104 } 105 106 // ----------------------------------------------------------------------------- 107 108 GraphicObject::GraphicObject( const Graphic& rGraphic, const String& rLink, const GraphicManager* pMgr ) : 109 maGraphic ( rGraphic ), 110 mpLink ( rLink.Len() ? ( new String( rLink ) ) : NULL ), 111 mpUserData ( NULL ) 112 { 113 ImplConstruct(); 114 ImplAssignGraphicData(); 115 ImplSetGraphicManager( pMgr ); 116 } 117 118 // ----------------------------------------------------------------------------- 119 120 GraphicObject::GraphicObject( const GraphicObject& rGraphicObj, const GraphicManager* pMgr ) : 121 SvDataCopyStream(), 122 maGraphic ( rGraphicObj.GetGraphic() ), 123 maAttr ( rGraphicObj.maAttr ), 124 mpLink ( rGraphicObj.mpLink ? ( new String( *rGraphicObj.mpLink ) ) : NULL ), 125 mpUserData ( rGraphicObj.mpUserData ? ( new String( *rGraphicObj.mpUserData ) ) : NULL ) 126 { 127 ImplConstruct(); 128 ImplAssignGraphicData(); 129 ImplSetGraphicManager( pMgr, NULL, &rGraphicObj ); 130 } 131 132 // ----------------------------------------------------------------------------- 133 134 GraphicObject::GraphicObject( const ByteString& rUniqueID, const GraphicManager* pMgr ) : 135 mpLink ( NULL ), 136 mpUserData ( NULL ) 137 { 138 ImplConstruct(); 139 140 // assign default properties 141 ImplAssignGraphicData(); 142 143 ImplSetGraphicManager( pMgr, &rUniqueID ); 144 145 // update properties 146 ImplAssignGraphicData(); 147 } 148 149 // ----------------------------------------------------------------------------- 150 151 GraphicObject::~GraphicObject() 152 { 153 if( mpMgr ) 154 { 155 mpMgr->ImplUnregisterObj( *this ); 156 157 if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() ) 158 delete mpGlobalMgr, mpGlobalMgr = NULL; 159 } 160 161 delete mpSwapOutTimer; 162 delete mpSwapStreamHdl; 163 delete mpLink; 164 delete mpUserData; 165 delete mpSimpleCache; 166 } 167 168 // ----------------------------------------------------------------------------- 169 170 void GraphicObject::ImplConstruct() 171 { 172 mpMgr = NULL; 173 mpSwapStreamHdl = NULL; 174 mpSwapOutTimer = NULL; 175 mpSimpleCache = NULL; 176 mnAnimationLoopCount = 0; 177 mbAutoSwapped = sal_False; 178 mbIsInSwapIn = sal_False; 179 mbIsInSwapOut = sal_False; 180 } 181 182 // ----------------------------------------------------------------------------- 183 184 void GraphicObject::ImplAssignGraphicData() 185 { 186 maPrefSize = maGraphic.GetPrefSize(); 187 maPrefMapMode = maGraphic.GetPrefMapMode(); 188 mnSizeBytes = maGraphic.GetSizeBytes(); 189 meType = maGraphic.GetType(); 190 mbTransparent = maGraphic.IsTransparent(); 191 mbAlpha = maGraphic.IsAlpha(); 192 mbAnimated = maGraphic.IsAnimated(); 193 mbEPS = maGraphic.IsEPS(); 194 mbIsRenderGraphic = maGraphic.IsRenderGraphic(); 195 mbHasRenderGraphic = maGraphic.HasRenderGraphic(); 196 mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 ); 197 } 198 199 // ----------------------------------------------------------------------------- 200 201 void GraphicObject::ImplSetGraphicManager( const GraphicManager* pMgr, const ByteString* pID, const GraphicObject* pCopyObj ) 202 { 203 if( !mpMgr || ( pMgr != mpMgr ) ) 204 { 205 if( !pMgr && mpMgr && ( mpMgr == mpGlobalMgr ) ) 206 return; 207 else 208 { 209 if( mpMgr ) 210 { 211 mpMgr->ImplUnregisterObj( *this ); 212 213 if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() ) 214 delete mpGlobalMgr, mpGlobalMgr = NULL; 215 } 216 217 if( !pMgr ) 218 { 219 if( !mpGlobalMgr ) 220 { 221 SvtCacheOptions aCacheOptions; 222 223 mpGlobalMgr = new GraphicManager( aCacheOptions.GetGraphicManagerTotalCacheSize(), 224 aCacheOptions.GetGraphicManagerObjectCacheSize() ); 225 mpGlobalMgr->SetCacheTimeout( aCacheOptions.GetGraphicManagerObjectReleaseTime() ); 226 } 227 228 mpMgr = mpGlobalMgr; 229 } 230 else 231 mpMgr = (GraphicManager*) pMgr; 232 233 mpMgr->ImplRegisterObj( *this, maGraphic, pID, pCopyObj ); 234 } 235 } 236 } 237 238 // ----------------------------------------------------------------------------- 239 240 void GraphicObject::ImplAutoSwapIn() 241 { 242 if( IsSwappedOut() ) 243 { 244 if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) ) 245 mbAutoSwapped = sal_False; 246 else 247 { 248 mbIsInSwapIn = sal_True; 249 250 if( maGraphic.SwapIn() ) 251 mbAutoSwapped = sal_False; 252 else 253 { 254 SvStream* pStream = GetSwapStream(); 255 256 if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream ) 257 { 258 if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream ) 259 { 260 if( HasLink() ) 261 { 262 String aURLStr; 263 264 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( GetLink(), aURLStr ) ) 265 { 266 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_READ ); 267 268 if( pIStm ) 269 { 270 (*pIStm) >> maGraphic; 271 mbAutoSwapped = ( maGraphic.GetType() != GRAPHIC_NONE ); 272 delete pIStm; 273 } 274 } 275 } 276 } 277 else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream ) 278 mbAutoSwapped = !maGraphic.SwapIn(); 279 else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream ) 280 mbAutoSwapped = maGraphic.IsSwapOut(); 281 else 282 { 283 mbAutoSwapped = !maGraphic.SwapIn( pStream ); 284 delete pStream; 285 } 286 } 287 else 288 { 289 DBG_ASSERT( ( GRAPHIC_NONE == meType ) || ( GRAPHIC_DEFAULT == meType ), 290 "GraphicObject::ImplAutoSwapIn: could not get stream to swap in graphic! (=>KA)" ); 291 } 292 } 293 294 mbIsInSwapIn = sal_False; 295 296 if( !mbAutoSwapped && mpMgr ) 297 mpMgr->ImplGraphicObjectWasSwappedIn( *this ); 298 } 299 } 300 } 301 302 // ----------------------------------------------------------------------------- 303 sal_Bool GraphicObject::ImplGetCropParams( OutputDevice* pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr, 304 PolyPolygon& rClipPolyPoly, sal_Bool& bRectClipRegion ) const 305 { 306 sal_Bool bRet = sal_False; 307 308 if( GetType() != GRAPHIC_NONE ) 309 { 310 Polygon aClipPoly( Rectangle( rPt, rSz ) ); 311 const sal_uInt16 nRot10 = pAttr->GetRotation() % 3600; 312 const Point aOldOrigin( rPt ); 313 // --> OD 2005-09-30 #i54875# - It's not needed to get the graphic again. 314 // const Graphic& rGraphic = GetGraphic(); 315 // <-- 316 const MapMode aMap100( MAP_100TH_MM ); 317 Size aSize100; 318 long nTotalWidth, nTotalHeight; 319 long nNewLeft, nNewTop, nNewRight, nNewBottom; 320 double fScale; 321 322 if( nRot10 ) 323 { 324 aClipPoly.Rotate( rPt, nRot10 ); 325 bRectClipRegion = sal_False; 326 } 327 else 328 bRectClipRegion = sal_True; 329 330 rClipPolyPoly = aClipPoly; 331 332 // --> OD 2005-09-30 #i54875# - directly access member <maGraphic> to 333 // get <PrefSize> and <PrefMapMode>. 334 // if( rGraphic.GetPrefMapMode() == MAP_PIXEL ) 335 // aSize100 = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), aMap100 ); 336 // else 337 // aSize100 = pOut->LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), aMap100 ); 338 if( maGraphic.GetPrefMapMode() == MAP_PIXEL ) 339 aSize100 = Application::GetDefaultDevice()->PixelToLogic( maGraphic.GetPrefSize(), aMap100 ); 340 else 341 { 342 MapMode m(maGraphic.GetPrefMapMode()); 343 aSize100 = pOut->LogicToLogic( maGraphic.GetPrefSize(), &m, &aMap100 ); 344 } 345 // <-- 346 347 nTotalWidth = aSize100.Width() - pAttr->GetLeftCrop() - pAttr->GetRightCrop(); 348 nTotalHeight = aSize100.Height() - pAttr->GetTopCrop() - pAttr->GetBottomCrop(); 349 350 if( aSize100.Width() > 0 && aSize100.Height() > 0 && nTotalWidth > 0 && nTotalHeight > 0 ) 351 { 352 fScale = (double) aSize100.Width() / nTotalWidth; 353 nNewLeft = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_HORZ ) ? pAttr->GetRightCrop() : pAttr->GetLeftCrop() ) * fScale ); 354 nNewRight = nNewLeft + FRound( aSize100.Width() * fScale ) - 1; 355 356 fScale = (double) rSz.Width() / aSize100.Width(); 357 rPt.X() += FRound( nNewLeft * fScale ); 358 rSz.Width() = FRound( ( nNewRight - nNewLeft + 1 ) * fScale ); 359 360 fScale = (double) aSize100.Height() / nTotalHeight; 361 nNewTop = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_VERT ) ? pAttr->GetBottomCrop() : pAttr->GetTopCrop() ) * fScale ); 362 nNewBottom = nNewTop + FRound( aSize100.Height() * fScale ) - 1; 363 364 fScale = (double) rSz.Height() / aSize100.Height(); 365 rPt.Y() += FRound( nNewTop * fScale ); 366 rSz.Height() = FRound( ( nNewBottom - nNewTop + 1 ) * fScale ); 367 368 if( nRot10 ) 369 { 370 Polygon aOriginPoly( 1 ); 371 372 aOriginPoly[ 0 ] = rPt; 373 aOriginPoly.Rotate( aOldOrigin, nRot10 ); 374 rPt = aOriginPoly[ 0 ]; 375 } 376 377 bRet = sal_True; 378 } 379 } 380 381 return bRet; 382 } 383 384 // ----------------------------------------------------------------------------- 385 386 GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj ) 387 { 388 if( &rGraphicObj != this ) 389 { 390 mpMgr->ImplUnregisterObj( *this ); 391 392 delete mpSwapStreamHdl, mpSwapStreamHdl = NULL; 393 delete mpSimpleCache, mpSimpleCache = NULL; 394 delete mpLink; 395 delete mpUserData; 396 397 maGraphic = rGraphicObj.GetGraphic(); 398 maAttr = rGraphicObj.maAttr; 399 mpLink = rGraphicObj.mpLink ? new String( *rGraphicObj.mpLink ) : NULL; 400 mpUserData = rGraphicObj.mpUserData ? new String( *rGraphicObj.mpUserData ) : NULL; 401 ImplAssignGraphicData(); 402 mbAutoSwapped = sal_False; 403 mpMgr = rGraphicObj.mpMgr; 404 405 mpMgr->ImplRegisterObj( *this, maGraphic, NULL, &rGraphicObj ); 406 } 407 408 return *this; 409 } 410 411 // ----------------------------------------------------------------------------- 412 413 sal_Bool GraphicObject::operator==( const GraphicObject& rGraphicObj ) const 414 { 415 return( ( rGraphicObj.maGraphic == maGraphic ) && 416 ( rGraphicObj.maAttr == maAttr ) && 417 ( rGraphicObj.GetLink() == GetLink() ) ); 418 } 419 420 // ------------------------------------------------------------------------ 421 422 void GraphicObject::Load( SvStream& rIStm ) 423 { 424 rIStm >> *this; 425 } 426 427 // ------------------------------------------------------------------------ 428 429 void GraphicObject::Save( SvStream& rOStm ) 430 { 431 rOStm << *this; 432 } 433 434 // ------------------------------------------------------------------------ 435 436 void GraphicObject::Assign( const SvDataCopyStream& rCopyStream ) 437 { 438 *this = (const GraphicObject& ) rCopyStream; 439 } 440 441 // ----------------------------------------------------------------------------- 442 443 ByteString GraphicObject::GetUniqueID() const 444 { 445 if ( !IsInSwapIn() && ( IsEPS() || IsRenderGraphic() ) ) 446 const_cast<GraphicObject*>(this)->FireSwapInRequest(); 447 448 ByteString aRet; 449 450 if( mpMgr ) 451 aRet = mpMgr->ImplGetUniqueID( *this ); 452 453 return aRet; 454 } 455 456 // ----------------------------------------------------------------------------- 457 458 sal_uLong GraphicObject::GetChecksum() const 459 { 460 return( ( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() ) ? maGraphic.GetChecksum() : 0 ); 461 } 462 463 // ----------------------------------------------------------------------------- 464 465 SvStream* GraphicObject::GetSwapStream() const 466 { 467 return( HasSwapStreamHdl() ? (SvStream*) mpSwapStreamHdl->Call( (void*) this ) : GRFMGR_AUTOSWAPSTREAM_NONE ); 468 } 469 470 // ----------------------------------------------------------------------------- 471 472 // !!! to be removed 473 sal_uLong GraphicObject::GetReleaseFromCache() const 474 { 475 return 0; 476 } 477 478 // ----------------------------------------------------------------------------- 479 480 void GraphicObject::SetAttr( const GraphicAttr& rAttr ) 481 { 482 maAttr = rAttr; 483 484 if( mpSimpleCache && ( mpSimpleCache->maAttr != rAttr ) ) 485 delete mpSimpleCache, mpSimpleCache = NULL; 486 } 487 488 // ----------------------------------------------------------------------------- 489 490 void GraphicObject::SetLink() 491 { 492 if( mpLink ) 493 delete mpLink, mpLink = NULL; 494 } 495 496 // ----------------------------------------------------------------------------- 497 498 void GraphicObject::SetLink( const String& rLink ) 499 { 500 delete mpLink, mpLink = new String( rLink ); 501 } 502 503 // ----------------------------------------------------------------------------- 504 505 String GraphicObject::GetLink() const 506 { 507 if( mpLink ) 508 return *mpLink; 509 else 510 return String(); 511 } 512 513 // ----------------------------------------------------------------------------- 514 515 void GraphicObject::SetUserData() 516 { 517 if( mpUserData ) 518 delete mpUserData, mpUserData = NULL; 519 } 520 521 // ----------------------------------------------------------------------------- 522 523 void GraphicObject::SetUserData( const String& rUserData ) 524 { 525 delete mpUserData, mpUserData = new String( rUserData ); 526 } 527 528 // ----------------------------------------------------------------------------- 529 530 String GraphicObject::GetUserData() const 531 { 532 if( mpUserData ) 533 return *mpUserData; 534 else 535 return String(); 536 } 537 538 // ----------------------------------------------------------------------------- 539 540 void GraphicObject::SetSwapStreamHdl() 541 { 542 if( mpSwapStreamHdl ) 543 { 544 delete mpSwapOutTimer, mpSwapOutTimer = NULL; 545 delete mpSwapStreamHdl, mpSwapStreamHdl = NULL; 546 } 547 } 548 549 // ----------------------------------------------------------------------------- 550 551 void GraphicObject::SetSwapStreamHdl( const Link& rHdl, const sal_uLong nSwapOutTimeout ) 552 { 553 delete mpSwapStreamHdl, mpSwapStreamHdl = new Link( rHdl ); 554 555 if( nSwapOutTimeout ) 556 { 557 if( !mpSwapOutTimer ) 558 { 559 mpSwapOutTimer = new Timer; 560 mpSwapOutTimer->SetTimeoutHdl( LINK( this, GraphicObject, ImplAutoSwapOutHdl ) ); 561 } 562 563 mpSwapOutTimer->SetTimeout( nSwapOutTimeout ); 564 mpSwapOutTimer->Start(); 565 } 566 else 567 delete mpSwapOutTimer, mpSwapOutTimer = NULL; 568 } 569 570 // ----------------------------------------------------------------------------- 571 572 Link GraphicObject::GetSwapStreamHdl() const 573 { 574 if( mpSwapStreamHdl ) 575 return *mpSwapStreamHdl; 576 else 577 return Link(); 578 } 579 580 // ----------------------------------------------------------------------------- 581 582 void GraphicObject::FireSwapInRequest() 583 { 584 ImplAutoSwapIn(); 585 } 586 587 // ----------------------------------------------------------------------------- 588 589 void GraphicObject::FireSwapOutRequest() 590 { 591 ImplAutoSwapOutHdl( NULL ); 592 } 593 594 // ----------------------------------------------------------------------------- 595 596 void GraphicObject::GraphicManagerDestroyed() 597 { 598 // we're alive, but our manager doesn't live anymore ==> connect to default manager 599 mpMgr = NULL; 600 ImplSetGraphicManager( NULL ); 601 } 602 603 // ----------------------------------------------------------------------------- 604 605 void GraphicObject::SetGraphicManager( const GraphicManager& rMgr ) 606 { 607 ImplSetGraphicManager( &rMgr ); 608 } 609 610 // ----------------------------------------------------------------------------- 611 612 sal_Bool GraphicObject::IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz, 613 const GraphicAttr* pAttr, sal_uLong nFlags ) const 614 { 615 sal_Bool bRet; 616 617 if( nFlags & GRFMGR_DRAW_CACHED ) 618 { 619 // --> OD 2005-10-11 #i54875# - Consider cropped graphics. 620 // Note: The graphic manager caches a cropped graphic with its 621 // uncropped position and size. 622 // bRet = mpMgr->IsInCache( pOut, rPt, rSz, *this, ( pAttr ? *pAttr : GetAttr() ) ); 623 Point aPt( rPt ); 624 Size aSz( rSz ); 625 if ( pAttr->IsCropped() ) 626 { 627 PolyPolygon aClipPolyPoly; 628 sal_Bool bRectClip; 629 ImplGetCropParams( pOut, aPt, aSz, pAttr, aClipPolyPoly, bRectClip ); 630 } 631 bRet = mpMgr->IsInCache( pOut, aPt, aSz, *this, ( pAttr ? *pAttr : GetAttr() ) ); 632 } 633 else 634 bRet = sal_False; 635 636 return bRet; 637 } 638 639 // ----------------------------------------------------------------------------- 640 641 void GraphicObject::ReleaseFromCache() 642 { 643 644 mpMgr->ReleaseFromCache( *this ); 645 } 646 647 // ----------------------------------------------------------------------------- 648 649 void GraphicObject::SetAnimationNotifyHdl( const Link& rLink ) 650 { 651 maGraphic.SetAnimationNotifyHdl( rLink ); 652 } 653 654 // ----------------------------------------------------------------------------- 655 656 List* GraphicObject::GetAnimationInfoList() const 657 { 658 return maGraphic.GetAnimationInfoList(); 659 } 660 661 // ----------------------------------------------------------------------------- 662 663 sal_Bool GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz, 664 const GraphicAttr* pAttr, sal_uLong nFlags ) 665 { 666 GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() ); 667 Point aPt( rPt ); 668 Size aSz( rSz ); 669 const sal_uInt32 nOldDrawMode = pOut->GetDrawMode(); 670 sal_Bool bCropped = aAttr.IsCropped(); 671 sal_Bool bCached = sal_False; 672 sal_Bool bRet; 673 674 // #i29534# Provide output rects for PDF writer 675 Rectangle aCropRect; 676 677 if( !( GRFMGR_DRAW_USE_DRAWMODE_SETTINGS & nFlags ) ) 678 pOut->SetDrawMode( nOldDrawMode & ( ~( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ) ) ); 679 680 // mirrored horizontically 681 if( aSz.Width() < 0L ) 682 { 683 aPt.X() += aSz.Width() + 1; 684 aSz.Width() = -aSz.Width(); 685 aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_HORZ ); 686 } 687 688 // mirrored vertically 689 if( aSz.Height() < 0L ) 690 { 691 aPt.Y() += aSz.Height() + 1; 692 aSz.Height() = -aSz.Height(); 693 aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_VERT ); 694 } 695 696 if( bCropped ) 697 { 698 PolyPolygon aClipPolyPoly; 699 sal_Bool bRectClip; 700 const sal_Bool bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip ); 701 702 pOut->Push( PUSH_CLIPREGION ); 703 704 if( bCrop ) 705 { 706 if( bRectClip ) 707 { 708 // #i29534# Store crop rect for later forwarding to 709 // PDF writer 710 aCropRect = aClipPolyPoly.GetBoundRect(); 711 pOut->IntersectClipRegion( aCropRect ); 712 } 713 else 714 { 715 pOut->IntersectClipRegion( aClipPolyPoly ); 716 } 717 } 718 } 719 720 bRet = mpMgr->DrawObj( pOut, aPt, aSz, *this, aAttr, nFlags, bCached ); 721 722 if( bCropped ) 723 pOut->Pop(); 724 725 pOut->SetDrawMode( nOldDrawMode ); 726 727 // #i29534# Moved below OutDev restoration, to avoid multiple swap-ins 728 // (code above needs to call GetGraphic twice) 729 if( bCached ) 730 { 731 if( mpSwapOutTimer ) 732 mpSwapOutTimer->Start(); 733 else 734 FireSwapOutRequest(); 735 } 736 737 return bRet; 738 } 739 740 // --> OD 2010-01-04 #i105243# 741 sal_Bool GraphicObject::DrawWithPDFHandling( OutputDevice& rOutDev, 742 const Point& rPt, const Size& rSz, 743 const GraphicAttr* pGrfAttr, 744 const sal_uLong nFlags ) 745 { 746 const GraphicAttr aGrfAttr( pGrfAttr ? *pGrfAttr : GetAttr() ); 747 748 // Notify PDF writer about linked graphic (if any) 749 sal_Bool bWritingPdfLinkedGraphic( sal_False ); 750 Point aPt( rPt ); 751 Size aSz( rSz ); 752 Rectangle aCropRect; 753 vcl::PDFExtOutDevData* pPDFExtOutDevData = 754 dynamic_cast<vcl::PDFExtOutDevData*>(rOutDev.GetExtOutDevData()); 755 if( pPDFExtOutDevData ) 756 { 757 // only delegate image handling to PDF, if no special treatment is necessary 758 if( GetGraphic().IsLink() && 759 rSz.Width() > 0L && 760 rSz.Height() > 0L && 761 !aGrfAttr.IsSpecialDrawMode() && 762 !aGrfAttr.IsMirrored() && 763 !aGrfAttr.IsRotated() && 764 !aGrfAttr.IsAdjusted() ) 765 { 766 bWritingPdfLinkedGraphic = true; 767 768 if( aGrfAttr.IsCropped() ) 769 { 770 PolyPolygon aClipPolyPoly; 771 sal_Bool bRectClip; 772 const sal_Bool bCrop = ImplGetCropParams( &rOutDev, 773 aPt, aSz, 774 &aGrfAttr, 775 aClipPolyPoly, 776 bRectClip ); 777 if ( bCrop && bRectClip ) 778 { 779 aCropRect = aClipPolyPoly.GetBoundRect(); 780 } 781 } 782 783 pPDFExtOutDevData->BeginGroup(); 784 } 785 } 786 787 sal_Bool bRet = Draw( &rOutDev, rPt, rSz, &aGrfAttr, nFlags ); 788 789 // Notify PDF writer about linked graphic (if any) 790 if( bWritingPdfLinkedGraphic ) 791 { 792 pPDFExtOutDevData->EndGroup( const_cast< Graphic& >(GetGraphic()), 793 aGrfAttr.GetTransparency(), 794 Rectangle( aPt, aSz ), 795 aCropRect ); 796 } 797 798 return bRet; 799 } 800 // <-- 801 802 // ----------------------------------------------------------------------------- 803 804 sal_Bool GraphicObject::DrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSize, 805 const Size& rOffset, const GraphicAttr* pAttr, sal_uLong nFlags, int nTileCacheSize1D ) 806 { 807 if( pOut == NULL || rSize.Width() == 0 || rSize.Height() == 0 ) 808 return sal_False; 809 810 const MapMode aOutMapMode( pOut->GetMapMode() ); 811 const MapMode aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() ); 812 // #106258# Clamp size to 1 for zero values. This is okay, since 813 // logical size of zero is handled above already 814 const Size aOutTileSize( ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Width() ), 815 ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Height() ) ); 816 817 //#i69780 clip final tile size to a sane max size 818 while (((sal_Int64)rSize.Width() * nTileCacheSize1D) > SAL_MAX_UINT16) 819 nTileCacheSize1D /= 2; 820 while (((sal_Int64)rSize.Height() * nTileCacheSize1D) > SAL_MAX_UINT16) 821 nTileCacheSize1D /= 2; 822 823 return ImplDrawTiled( pOut, rArea, aOutTileSize, rOffset, pAttr, nFlags, nTileCacheSize1D ); 824 } 825 826 // ----------------------------------------------------------------------------- 827 828 sal_Bool GraphicObject::StartAnimation( OutputDevice* pOut, const Point& rPt, const Size& rSz, 829 long nExtraData, const GraphicAttr* pAttr, sal_uLong /*nFlags*/, 830 OutputDevice* pFirstFrameOutDev ) 831 { 832 sal_Bool bRet = sal_False; 833 834 GetGraphic(); 835 836 if( !IsSwappedOut() ) 837 { 838 const GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() ); 839 840 if( mbAnimated ) 841 { 842 Point aPt( rPt ); 843 Size aSz( rSz ); 844 sal_Bool bCropped = aAttr.IsCropped(); 845 846 if( bCropped ) 847 { 848 PolyPolygon aClipPolyPoly; 849 sal_Bool bRectClip; 850 const sal_Bool bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip ); 851 852 pOut->Push( PUSH_CLIPREGION ); 853 854 if( bCrop ) 855 { 856 if( bRectClip ) 857 pOut->IntersectClipRegion( aClipPolyPoly.GetBoundRect() ); 858 else 859 pOut->IntersectClipRegion( aClipPolyPoly ); 860 } 861 } 862 863 if( !mpSimpleCache || ( mpSimpleCache->maAttr != aAttr ) || pFirstFrameOutDev ) 864 { 865 if( mpSimpleCache ) 866 delete mpSimpleCache; 867 868 mpSimpleCache = new GrfSimpleCacheObj( GetTransformedGraphic( &aAttr ), aAttr ); 869 mpSimpleCache->maGraphic.SetAnimationNotifyHdl( GetAnimationNotifyHdl() ); 870 } 871 872 mpSimpleCache->maGraphic.StartAnimation( pOut, aPt, aSz, nExtraData, pFirstFrameOutDev ); 873 874 if( bCropped ) 875 pOut->Pop(); 876 877 bRet = sal_True; 878 } 879 else 880 bRet = Draw( pOut, rPt, rSz, &aAttr, GRFMGR_DRAW_STANDARD ); 881 } 882 883 return bRet; 884 } 885 886 // ----------------------------------------------------------------------------- 887 888 void GraphicObject::StopAnimation( OutputDevice* pOut, long nExtraData ) 889 { 890 if( mpSimpleCache ) 891 mpSimpleCache->maGraphic.StopAnimation( pOut, nExtraData ); 892 } 893 894 // ----------------------------------------------------------------------------- 895 896 const Graphic& GraphicObject::GetGraphic() const 897 { 898 if( mbAutoSwapped ) 899 ( (GraphicObject*) this )->ImplAutoSwapIn(); 900 901 return maGraphic; 902 } 903 904 // ----------------------------------------------------------------------------- 905 906 void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj ) 907 { 908 mpMgr->ImplUnregisterObj( *this ); 909 910 if( mpSwapOutTimer ) 911 mpSwapOutTimer->Stop(); 912 913 maGraphic = rGraphic; 914 mbAutoSwapped = sal_False; 915 ImplAssignGraphicData(); 916 delete mpLink, mpLink = NULL; 917 delete mpSimpleCache, mpSimpleCache = NULL; 918 919 mpMgr->ImplRegisterObj( *this, maGraphic, 0, pCopyObj); 920 921 if( mpSwapOutTimer ) 922 mpSwapOutTimer->Start(); 923 } 924 925 // ----------------------------------------------------------------------------- 926 927 void GraphicObject::SetGraphic( const Graphic& rGraphic, const String& rLink ) 928 { 929 SetGraphic( rGraphic ); 930 mpLink = new String( rLink ); 931 } 932 933 // ----------------------------------------------------------------------------- 934 935 Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMode& rDestMap, const GraphicAttr& rAttr ) const 936 { 937 // #104550# Extracted from svx/source/svdraw/svdograf.cxx 938 Graphic aTransGraphic( maGraphic ); 939 const GraphicType eType = GetType(); 940 const Size aSrcSize( aTransGraphic.GetPrefSize() ); 941 942 // #104115# Convert the crop margins to graphic object mapmode 943 const MapMode aMapGraph( aTransGraphic.GetPrefMapMode() ); 944 const MapMode aMap100( MAP_100TH_MM ); 945 946 Size aCropLeftTop; 947 Size aCropRightBottom; 948 949 if( GRAPHIC_GDIMETAFILE == eType ) 950 { 951 GDIMetaFile aMtf( aTransGraphic.GetGDIMetaFile() ); 952 953 if( aMapGraph == MAP_PIXEL ) 954 { 955 aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(), 956 rAttr.GetTopCrop() ), 957 aMap100 ); 958 aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(), 959 rAttr.GetBottomCrop() ), 960 aMap100 ); 961 } 962 else 963 { 964 aCropLeftTop = OutputDevice::LogicToLogic( Size( rAttr.GetLeftCrop(), 965 rAttr.GetTopCrop() ), 966 aMap100, 967 aMapGraph ); 968 aCropRightBottom = OutputDevice::LogicToLogic( Size( rAttr.GetRightCrop(), 969 rAttr.GetBottomCrop() ), 970 aMap100, 971 aMapGraph ); 972 } 973 974 // #104115# If the metafile is cropped, give it a special 975 // treatment: clip against the remaining area, scale up such 976 // that this area later fills the desired size, and move the 977 // origin to the upper left edge of that area. 978 if( rAttr.IsCropped() ) 979 { 980 const MapMode aMtfMapMode( aMtf.GetPrefMapMode() ); 981 982 Rectangle aClipRect( aMtfMapMode.GetOrigin().X() + aCropLeftTop.Width(), 983 aMtfMapMode.GetOrigin().Y() + aCropLeftTop.Height(), 984 aMtfMapMode.GetOrigin().X() + aSrcSize.Width() - aCropRightBottom.Width(), 985 aMtfMapMode.GetOrigin().Y() + aSrcSize.Height() - aCropRightBottom.Height() ); 986 987 // #104115# To correctly crop rotated metafiles, clip by view rectangle 988 aMtf.AddAction( new MetaISectRectClipRegionAction( aClipRect ), 0 ); 989 990 // #104115# To crop the metafile, scale larger than the output rectangle 991 aMtf.Scale( (double)rDestSize.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()), 992 (double)rDestSize.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) ); 993 994 // #104115# Adapt the pref size by hand (scale changes it 995 // proportionally, but we want it to be smaller than the 996 // former size, to crop the excess out) 997 aMtf.SetPrefSize( Size( (long)((double)rDestSize.Width() * (1.0 + (aCropLeftTop.Width() + aCropRightBottom.Width()) / aSrcSize.Width()) + .5), 998 (long)((double)rDestSize.Height() * (1.0 + (aCropLeftTop.Height() + aCropRightBottom.Height()) / aSrcSize.Height()) + .5) ) ); 999 1000 // #104115# Adapt the origin of the new mapmode, such that it 1001 // is shifted to the place where the cropped output starts 1002 Point aNewOrigin( (long)((double)aMtfMapMode.GetOrigin().X() + rDestSize.Width() * aCropLeftTop.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()) + .5), 1003 (long)((double)aMtfMapMode.GetOrigin().Y() + rDestSize.Height() * aCropLeftTop.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) + .5) ); 1004 MapMode aNewMap( rDestMap ); 1005 aNewMap.SetOrigin( OutputDevice::LogicToLogic(aNewOrigin, aMtfMapMode, rDestMap) ); 1006 aMtf.SetPrefMapMode( aNewMap ); 1007 } 1008 else 1009 { 1010 aMtf.Scale( Fraction( rDestSize.Width(), aSrcSize.Width() ), Fraction( rDestSize.Height(), aSrcSize.Height() ) ); 1011 aMtf.SetPrefMapMode( rDestMap ); 1012 } 1013 1014 aTransGraphic = aMtf; 1015 } 1016 else if( GRAPHIC_BITMAP == eType ) 1017 { 1018 BitmapEx aBitmapEx( aTransGraphic.GetBitmapEx() ); 1019 1020 // convert crops to pixel 1021 aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(), 1022 rAttr.GetTopCrop() ), 1023 aMap100 ); 1024 aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(), 1025 rAttr.GetBottomCrop() ), 1026 aMap100 ); 1027 1028 // convert from prefmapmode to pixel 1029 const Size aSrcSizePixel( Application::GetDefaultDevice()->LogicToPixel( aSrcSize, 1030 aMapGraph ) ); 1031 1032 // setup crop rectangle in pixel 1033 Rectangle aCropRect( aCropLeftTop.Width(), aCropLeftTop.Height(), 1034 aSrcSizePixel.Width() - aCropRightBottom.Width(), 1035 aSrcSizePixel.Height() - aCropRightBottom.Height() ); 1036 1037 // #105641# Also crop animations 1038 if( aTransGraphic.IsAnimated() ) 1039 { 1040 sal_uInt16 nFrame; 1041 Animation aAnim( aTransGraphic.GetAnimation() ); 1042 1043 for( nFrame=0; nFrame<aAnim.Count(); ++nFrame ) 1044 { 1045 AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) ); 1046 1047 if( !aCropRect.IsInside( Rectangle(aAnimBmp.aPosPix, aAnimBmp.aSizePix) ) ) 1048 { 1049 // setup actual cropping (relative to frame position) 1050 Rectangle aCropRectRel( aCropRect ); 1051 aCropRectRel.Move( -aAnimBmp.aPosPix.X(), 1052 -aAnimBmp.aPosPix.Y() ); 1053 1054 // cropping affects this frame, apply it then 1055 // do _not_ apply enlargement, this is done below 1056 ImplTransformBitmap( aAnimBmp.aBmpEx, rAttr, Size(), Size(), 1057 aCropRectRel, rDestSize, sal_False ); 1058 1059 aAnim.Replace( aAnimBmp, nFrame ); 1060 } 1061 // else: bitmap completely within crop area, 1062 // i.e. nothing is cropped away 1063 } 1064 1065 // now, apply enlargement (if any) through global animation size 1066 if( aCropLeftTop.Width() < 0 || 1067 aCropLeftTop.Height() < 0 || 1068 aCropRightBottom.Width() < 0 || 1069 aCropRightBottom.Height() < 0 ) 1070 { 1071 Size aNewSize( aAnim.GetDisplaySizePixel() ); 1072 aNewSize.Width() += aCropRightBottom.Width() < 0 ? -aCropRightBottom.Width() : 0; 1073 aNewSize.Width() += aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0; 1074 aNewSize.Height() += aCropRightBottom.Height() < 0 ? -aCropRightBottom.Height() : 0; 1075 aNewSize.Height() += aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0; 1076 aAnim.SetDisplaySizePixel( aNewSize ); 1077 } 1078 1079 // if topleft has changed, we must move all frames to the 1080 // right and bottom, resp. 1081 if( aCropLeftTop.Width() < 0 || 1082 aCropLeftTop.Height() < 0 ) 1083 { 1084 Point aPosOffset( aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0, 1085 aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0 ); 1086 1087 for( nFrame=0; nFrame<aAnim.Count(); ++nFrame ) 1088 { 1089 AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) ); 1090 1091 aAnimBmp.aPosPix += aPosOffset; 1092 1093 aAnim.Replace( aAnimBmp, nFrame ); 1094 } 1095 } 1096 1097 aTransGraphic = aAnim; 1098 } 1099 else 1100 { 1101 BitmapEx aBmpEx( aTransGraphic.GetBitmapEx() ); 1102 1103 ImplTransformBitmap( aBmpEx, rAttr, aCropLeftTop, aCropRightBottom, 1104 aCropRect, rDestSize, sal_True ); 1105 1106 aTransGraphic = aBmpEx; 1107 } 1108 1109 aTransGraphic.SetPrefSize( rDestSize ); 1110 aTransGraphic.SetPrefMapMode( rDestMap ); 1111 } 1112 1113 GraphicObject aGrfObj( aTransGraphic ); 1114 aTransGraphic = aGrfObj.GetTransformedGraphic( &rAttr ); 1115 1116 return aTransGraphic; 1117 } 1118 1119 // ----------------------------------------------------------------------------- 1120 1121 Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const // TODO: Change to Impl 1122 { 1123 GetGraphic(); 1124 1125 Graphic aGraphic; 1126 GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() ); 1127 1128 if( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() ) 1129 { 1130 if( aAttr.IsSpecialDrawMode() || aAttr.IsAdjusted() || aAttr.IsMirrored() || aAttr.IsRotated() || aAttr.IsTransparent() ) 1131 { 1132 if( GetType() == GRAPHIC_BITMAP ) 1133 { 1134 if( IsAnimated() ) 1135 { 1136 Animation aAnimation( maGraphic.GetAnimation() ); 1137 GraphicManager::ImplAdjust( aAnimation, aAttr, ADJUSTMENT_ALL ); 1138 aAnimation.SetLoopCount( mnAnimationLoopCount ); 1139 aGraphic = aAnimation; 1140 } 1141 else 1142 { 1143 BitmapEx aBmpEx( maGraphic.GetBitmapEx() ); 1144 GraphicManager::ImplAdjust( aBmpEx, aAttr, ADJUSTMENT_ALL ); 1145 aGraphic = aBmpEx; 1146 } 1147 } 1148 else 1149 { 1150 GDIMetaFile aMtf( maGraphic.GetGDIMetaFile() ); 1151 GraphicManager::ImplAdjust( aMtf, aAttr, ADJUSTMENT_ALL ); 1152 aGraphic = aMtf; 1153 } 1154 } 1155 else 1156 { 1157 if( ( GetType() == GRAPHIC_BITMAP ) && IsAnimated() ) 1158 { 1159 Animation aAnimation( maGraphic.GetAnimation() ); 1160 aAnimation.SetLoopCount( mnAnimationLoopCount ); 1161 aGraphic = aAnimation; 1162 } 1163 else 1164 aGraphic = maGraphic; 1165 } 1166 } 1167 1168 return aGraphic; 1169 } 1170 1171 // ----------------------------------------------------------------------------- 1172 1173 void GraphicObject::ResetAnimationLoopCount() 1174 { 1175 if( IsAnimated() && !IsSwappedOut() ) 1176 { 1177 maGraphic.ResetAnimationLoopCount(); 1178 1179 if( mpSimpleCache ) 1180 mpSimpleCache->maGraphic.ResetAnimationLoopCount(); 1181 } 1182 } 1183 1184 // ----------------------------------------------------------------------------- 1185 1186 sal_Bool GraphicObject::SwapOut() 1187 { 1188 sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut() : sal_False ); 1189 1190 if( bRet && mpMgr ) 1191 mpMgr->ImplGraphicObjectWasSwappedOut( *this ); 1192 1193 return bRet; 1194 } 1195 1196 // ----------------------------------------------------------------------------- 1197 1198 sal_Bool GraphicObject::SwapOut( SvStream* pOStm ) 1199 { 1200 sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut( pOStm ) : sal_False ); 1201 1202 if( bRet && mpMgr ) 1203 mpMgr->ImplGraphicObjectWasSwappedOut( *this ); 1204 1205 return bRet; 1206 } 1207 1208 // ----------------------------------------------------------------------------- 1209 1210 sal_Bool GraphicObject::SwapIn() 1211 { 1212 sal_Bool bRet; 1213 1214 if( mbAutoSwapped ) 1215 { 1216 ImplAutoSwapIn(); 1217 bRet = sal_True; 1218 } 1219 else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) ) 1220 bRet = sal_True; 1221 else 1222 { 1223 bRet = maGraphic.SwapIn(); 1224 1225 if( bRet && mpMgr ) 1226 mpMgr->ImplGraphicObjectWasSwappedIn( *this ); 1227 } 1228 1229 if( bRet ) 1230 ImplAssignGraphicData(); 1231 1232 return bRet; 1233 } 1234 1235 // ----------------------------------------------------------------------------- 1236 1237 sal_Bool GraphicObject::SwapIn( SvStream* pIStm ) 1238 { 1239 sal_Bool bRet; 1240 1241 if( mbAutoSwapped ) 1242 { 1243 ImplAutoSwapIn(); 1244 bRet = sal_True; 1245 } 1246 else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) ) 1247 bRet = sal_True; 1248 else 1249 { 1250 bRet = maGraphic.SwapIn( pIStm ); 1251 1252 if( bRet && mpMgr ) 1253 mpMgr->ImplGraphicObjectWasSwappedIn( *this ); 1254 } 1255 1256 if( bRet ) 1257 ImplAssignGraphicData(); 1258 1259 return bRet; 1260 } 1261 1262 // ----------------------------------------------------------------------------- 1263 1264 void GraphicObject::SetSwapState() 1265 { 1266 if( !IsSwappedOut() ) 1267 { 1268 mbAutoSwapped = sal_True; 1269 1270 if( mpMgr ) 1271 mpMgr->ImplGraphicObjectWasSwappedOut( *this ); 1272 } 1273 } 1274 1275 // ----------------------------------------------------------------------------- 1276 1277 IMPL_LINK( GraphicObject, ImplAutoSwapOutHdl, void*, EMPTYARG ) 1278 { 1279 if( !IsSwappedOut() ) 1280 { 1281 mbIsInSwapOut = sal_True; 1282 1283 SvStream* pStream = GetSwapStream(); 1284 1285 if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream ) 1286 { 1287 if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream ) 1288 mbAutoSwapped = SwapOut( NULL ); 1289 else 1290 { 1291 if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream ) 1292 mbAutoSwapped = SwapOut(); 1293 else 1294 { 1295 mbAutoSwapped = SwapOut( pStream ); 1296 delete pStream; 1297 } 1298 } 1299 } 1300 1301 mbIsInSwapOut = sal_False; 1302 } 1303 1304 if( mpSwapOutTimer ) 1305 mpSwapOutTimer->Start(); 1306 1307 return 0L; 1308 } 1309 1310 // ------------------------------------------------------------------------ 1311 1312 SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj ) 1313 { 1314 VersionCompat aCompat( rIStm, STREAM_READ ); 1315 Graphic aGraphic; 1316 GraphicAttr aAttr; 1317 ByteString aLink; 1318 sal_Bool bLink; 1319 1320 rIStm >> aGraphic >> aAttr >> bLink; 1321 1322 rGraphicObj.SetGraphic( aGraphic ); 1323 rGraphicObj.SetAttr( aAttr ); 1324 1325 if( bLink ) 1326 { 1327 rIStm >> aLink; 1328 rGraphicObj.SetLink( UniString( aLink, RTL_TEXTENCODING_UTF8 ) ); 1329 } 1330 else 1331 rGraphicObj.SetLink(); 1332 1333 rGraphicObj.SetSwapStreamHdl(); 1334 1335 return rIStm; 1336 } 1337 1338 // ------------------------------------------------------------------------ 1339 1340 SvStream& operator<<( SvStream& rOStm, const GraphicObject& rGraphicObj ) 1341 { 1342 VersionCompat aCompat( rOStm, STREAM_WRITE, 1 ); 1343 const sal_Bool bLink = rGraphicObj.HasLink(); 1344 1345 rOStm << rGraphicObj.GetGraphic() << rGraphicObj.GetAttr() << bLink; 1346 1347 if( bLink ) 1348 rOStm << ByteString( rGraphicObj.GetLink(), RTL_TEXTENCODING_UTF8 ); 1349 1350 return rOStm; 1351 } 1352 1353 #define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:" 1354 1355 GraphicObject GraphicObject::CreateGraphicObjectFromURL( const ::rtl::OUString &rURL ) 1356 { 1357 const String aURL( rURL ), aPrefix( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX) ); 1358 if( aURL.Search( aPrefix ) == 0 ) 1359 { 1360 // graphic manager url 1361 ByteString aUniqueID( String(rURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 )), RTL_TEXTENCODING_UTF8 ); 1362 return GraphicObject( aUniqueID ); 1363 } 1364 else 1365 { 1366 Graphic aGraphic; 1367 if ( aURL.Len() ) 1368 { 1369 SvStream* pStream = utl::UcbStreamHelper::CreateStream( aURL, STREAM_READ ); 1370 if( pStream ) 1371 GraphicConverter::Import( *pStream, aGraphic ); 1372 } 1373 1374 return GraphicObject( aGraphic ); 1375 } 1376 } 1377