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