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