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