1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_vcl.hxx" 26 27 #define ENABLE_BYTESTRING_STREAM_OPERATORS 28 #include <vcl/animate.hxx> 29 #include <tools/debug.hxx> 30 #include <tools/stream.hxx> 31 #include <rtl/crc.h> 32 #include <vcl/virdev.hxx> 33 #include <vcl/window.hxx> 34 #include <impanmvw.hxx> 35 DBG_NAME( Animation ) 36 37 // ----------- 38 // - Defines - 39 // ----------- 40 41 #define MIN_TIMEOUT 2L 42 #define INC_TIMEOUT 0L 43 44 // ----------- 45 // - statics - 46 // ----------- 47 48 sal_uLong Animation::mnAnimCount = 0UL; 49 50 // ------------------- 51 // - AnimationBitmap - 52 // ------------------- 53 54 sal_uLong AnimationBitmap::GetChecksum() const 55 { 56 sal_uInt32 nCrc = aBmpEx.GetChecksum(); 57 SVBT32 aBT32; 58 59 UInt32ToSVBT32( aPosPix.X(), aBT32 ); 60 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 61 62 UInt32ToSVBT32( aPosPix.Y(), aBT32 ); 63 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 64 65 UInt32ToSVBT32( aSizePix.Width(), aBT32 ); 66 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 67 68 UInt32ToSVBT32( aSizePix.Height(), aBT32 ); 69 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 70 71 UInt32ToSVBT32( (long) nWait, aBT32 ); 72 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 73 74 UInt32ToSVBT32( (long) eDisposal, aBT32 ); 75 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 76 77 UInt32ToSVBT32( (long) bUserInput, aBT32 ); 78 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 79 80 return nCrc; 81 } 82 83 // ------------- 84 // - Animation - 85 // ------------- 86 87 Animation::Animation() : 88 mnLoopCount ( 0 ), 89 mnLoops ( 0 ), 90 mnPos ( 0 ), 91 meCycleMode ( CYCLE_NORMAL ), 92 mbIsInAnimation ( sal_False ), 93 mbLoopTerminated ( sal_False ), 94 mbIsWaiting ( sal_False ) 95 { 96 DBG_CTOR( Animation, NULL ); 97 maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) ); 98 mpViewList = new List; 99 } 100 101 // ----------------------------------------------------------------------- 102 103 Animation::Animation( const Animation& rAnimation ) : 104 maBitmapEx ( rAnimation.maBitmapEx ), 105 maGlobalSize ( rAnimation.maGlobalSize ), 106 mnLoopCount ( rAnimation.mnLoopCount ), 107 mnPos ( rAnimation.mnPos ), 108 meCycleMode ( rAnimation.meCycleMode ), 109 mbIsInAnimation ( sal_False ), 110 mbLoopTerminated ( rAnimation.mbLoopTerminated ), 111 mbIsWaiting ( rAnimation.mbIsWaiting ) 112 { 113 DBG_CTOR( Animation, NULL ); 114 115 for( long i = 0, nCount = rAnimation.maList.Count(); i < nCount; i++ ) 116 maList.Insert( new AnimationBitmap( *(AnimationBitmap*) rAnimation.maList.GetObject( i ) ), LIST_APPEND ); 117 118 maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) ); 119 mpViewList = new List; 120 mnLoops = mbLoopTerminated ? 0 : mnLoopCount; 121 } 122 123 // ----------------------------------------------------------------------- 124 125 Animation::~Animation() 126 { 127 DBG_DTOR( Animation, NULL ); 128 129 if( mbIsInAnimation ) 130 Stop(); 131 132 for( void* pStepBmp = maList.First(); pStepBmp; pStepBmp = maList.Next() ) 133 delete (AnimationBitmap*) pStepBmp; 134 135 for( void* pView = mpViewList->First(); pView; pView = mpViewList->Next() ) 136 delete (ImplAnimView*) pView; 137 138 delete mpViewList; 139 } 140 141 // ----------------------------------------------------------------------- 142 143 Animation& Animation::operator=( const Animation& rAnimation ) 144 { 145 Clear(); 146 147 for( long i = 0, nCount = rAnimation.maList.Count(); i < nCount; i++ ) 148 maList.Insert( new AnimationBitmap( *(AnimationBitmap*) rAnimation.maList.GetObject( i ) ), LIST_APPEND ); 149 150 maGlobalSize = rAnimation.maGlobalSize; 151 maBitmapEx = rAnimation.maBitmapEx; 152 meCycleMode = rAnimation.meCycleMode; 153 mnLoopCount = rAnimation.mnLoopCount; 154 mnPos = rAnimation.mnPos; 155 mbLoopTerminated = rAnimation.mbLoopTerminated; 156 mbIsWaiting = rAnimation.mbIsWaiting; 157 mnLoops = mbLoopTerminated ? 0 : mnLoopCount; 158 159 return *this; 160 } 161 162 // ----------------------------------------------------------------------- 163 164 sal_Bool Animation::operator==( const Animation& rAnimation ) const 165 { 166 const sal_uLong nCount = maList.Count(); 167 sal_Bool bRet = sal_False; 168 169 if( rAnimation.maList.Count() == nCount && 170 rAnimation.maBitmapEx == maBitmapEx && 171 rAnimation.maGlobalSize == maGlobalSize && 172 rAnimation.meCycleMode == meCycleMode ) 173 { 174 bRet = sal_True; 175 176 for( sal_uLong n = 0; n < nCount; n++ ) 177 { 178 if( ( *(AnimationBitmap*) maList.GetObject( n ) ) != 179 ( *(AnimationBitmap*) rAnimation.maList.GetObject( n ) ) ) 180 { 181 bRet = sal_False; 182 break; 183 } 184 } 185 } 186 187 return bRet; 188 } 189 190 // ------------------------------------------------------------------ 191 192 sal_Bool Animation::IsEqual( const Animation& rAnimation ) const 193 { 194 const sal_uLong nCount = maList.Count(); 195 sal_Bool bRet = sal_False; 196 197 if( rAnimation.maList.Count() == nCount && 198 rAnimation.maBitmapEx.IsEqual( maBitmapEx ) && 199 rAnimation.maGlobalSize == maGlobalSize && 200 rAnimation.meCycleMode == meCycleMode ) 201 { 202 for( sal_uLong n = 0; ( n < nCount ) && !bRet; n++ ) 203 if( ( (AnimationBitmap*) maList.GetObject( n ) )->IsEqual( *(AnimationBitmap*) rAnimation.maList.GetObject( n ) ) ) 204 bRet = sal_True; 205 } 206 207 return bRet; 208 } 209 210 // ------------------------------------------------------------------ 211 212 sal_Bool Animation::IsEmpty() const 213 { 214 return( maBitmapEx.IsEmpty() && !maList.Count() ); 215 } 216 217 // ------------------------------------------------------------------ 218 219 void Animation::SetEmpty() 220 { 221 maTimer.Stop(); 222 mbIsInAnimation = sal_False; 223 maGlobalSize = Size(); 224 maBitmapEx.SetEmpty(); 225 226 for( void* pStepBmp = maList.First(); pStepBmp; pStepBmp = maList.Next() ) 227 delete (AnimationBitmap*) pStepBmp; 228 maList.Clear(); 229 230 for( void* pView = mpViewList->First(); pView; pView = mpViewList->Next() ) 231 delete (ImplAnimView*) pView; 232 mpViewList->Clear(); 233 } 234 235 // ----------------------------------------------------------------------- 236 237 void Animation::Clear() 238 { 239 SetEmpty(); 240 } 241 242 // ----------------------------------------------------------------------- 243 244 sal_Bool Animation::IsTransparent() const 245 { 246 Point aPoint; 247 Rectangle aRect( aPoint, maGlobalSize ); 248 sal_Bool bRet = sal_False; 249 250 // Falls irgendein 'kleines' Bildchen durch den Hintergrund 251 // ersetzt werden soll, muessen wir 'transparent' sein, um 252 // richtig dargestellt zu werden, da die Appl. aus Optimierungsgruenden 253 // kein Invalidate auf nicht-transp. Grafiken ausfuehren 254 for( long i = 0, nCount = maList.Count(); i < nCount; i++ ) 255 { 256 const AnimationBitmap* pAnimBmp = (AnimationBitmap*) maList.GetObject( i ); 257 258 if( DISPOSE_BACK == pAnimBmp->eDisposal && Rectangle( pAnimBmp->aPosPix, pAnimBmp->aSizePix ) != aRect ) 259 { 260 bRet = sal_True; 261 break; 262 } 263 } 264 265 if( !bRet ) 266 bRet = maBitmapEx.IsTransparent(); 267 268 return bRet; 269 } 270 271 // ----------------------------------------------------------------------- 272 273 sal_uLong Animation::GetSizeBytes() const 274 { 275 sal_uLong nSizeBytes = GetBitmapEx().GetSizeBytes(); 276 277 for( long i = 0, nCount = maList.Count(); i < nCount; i++ ) 278 { 279 const AnimationBitmap* pAnimBmp = (AnimationBitmap*) maList.GetObject( i ); 280 nSizeBytes += pAnimBmp->aBmpEx.GetSizeBytes(); 281 } 282 283 return nSizeBytes; 284 } 285 286 // ----------------------------------------------------------------------- 287 288 sal_uLong Animation::GetChecksum() const 289 { 290 SVBT32 aBT32; 291 sal_uInt32 nCrc = GetBitmapEx().GetChecksum(); 292 293 UInt32ToSVBT32( maList.Count(), aBT32 ); 294 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 295 296 UInt32ToSVBT32( maGlobalSize.Width(), aBT32 ); 297 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 298 299 UInt32ToSVBT32( maGlobalSize.Height(), aBT32 ); 300 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 301 302 UInt32ToSVBT32( (long) meCycleMode, aBT32 ); 303 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 304 305 for( long i = 0, nCount = maList.Count(); i < nCount; i++ ) 306 { 307 UInt32ToSVBT32( ( (AnimationBitmap*) maList.GetObject( i ) )->GetChecksum(), aBT32 ); 308 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 309 } 310 311 return nCrc; 312 } 313 314 // ----------------------------------------------------------------------- 315 316 sal_Bool Animation::Start( OutputDevice* pOut, const Point& rDestPt, long nExtraData, 317 OutputDevice* pFirstFrameOutDev ) 318 { 319 return Start( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ), nExtraData, pFirstFrameOutDev ); 320 } 321 322 // ----------------------------------------------------------------------- 323 324 sal_Bool Animation::Start( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz, long nExtraData, 325 OutputDevice* pFirstFrameOutDev ) 326 { 327 sal_Bool bRet = sal_False; 328 329 if( maList.Count() ) 330 { 331 if( ( pOut->GetOutDevType() == OUTDEV_WINDOW ) && !mbLoopTerminated && 332 ( ANIMATION_TIMEOUT_ON_CLICK != ( (AnimationBitmap*) maList.GetObject( mnPos ) )->nWait ) ) 333 { 334 ImplAnimView* pView; 335 ImplAnimView* pMatch = NULL; 336 337 for( pView = (ImplAnimView*) mpViewList->First(); pView; pView = (ImplAnimView*) mpViewList->Next() ) 338 { 339 if( pView->ImplMatches( pOut, nExtraData ) ) 340 { 341 if( pView->ImplGetOutPos() == rDestPt && 342 pView->ImplGetOutSizePix() == pOut->LogicToPixel( rDestSz ) ) 343 { 344 pView->ImplRepaint(); 345 pMatch = pView; 346 } 347 else 348 { 349 delete (ImplAnimView*) mpViewList->Remove( pView ); 350 pView = NULL; 351 } 352 353 break; 354 } 355 } 356 357 if( !mpViewList->Count() ) 358 { 359 maTimer.Stop(); 360 mbIsInAnimation = sal_False; 361 mnPos = 0UL; 362 } 363 364 if( !pMatch ) 365 mpViewList->Insert( new ImplAnimView( this, pOut, rDestPt, rDestSz, nExtraData, pFirstFrameOutDev ), LIST_APPEND ); 366 367 if( !mbIsInAnimation ) 368 { 369 ImplRestartTimer( ( (AnimationBitmap*) maList.GetObject( mnPos ) )->nWait ); 370 mbIsInAnimation = sal_True; 371 } 372 } 373 else 374 Draw( pOut, rDestPt, rDestSz ); 375 376 bRet = sal_True; 377 } 378 379 return bRet; 380 } 381 382 // ----------------------------------------------------------------------- 383 384 void Animation::Stop( OutputDevice* pOut, long nExtraData ) 385 { 386 ImplAnimView* pView = (ImplAnimView*) mpViewList->First(); 387 388 while( pView ) 389 { 390 if( pView->ImplMatches( pOut, nExtraData ) ) 391 { 392 delete (ImplAnimView*) mpViewList->Remove( pView ); 393 pView = (ImplAnimView*) mpViewList->GetCurObject(); 394 } 395 else 396 pView = (ImplAnimView*) mpViewList->Next(); 397 } 398 399 if( !mpViewList->Count() ) 400 { 401 maTimer.Stop(); 402 mbIsInAnimation = sal_False; 403 } 404 } 405 406 // ----------------------------------------------------------------------- 407 408 void Animation::Draw( OutputDevice* pOut, const Point& rDestPt ) const 409 { 410 Draw( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ) ); 411 } 412 413 // ----------------------------------------------------------------------- 414 415 void Animation::Draw( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz ) const 416 { 417 const sal_uLong nCount = maList.Count(); 418 419 if( nCount ) 420 { 421 AnimationBitmap* pObj = (AnimationBitmap*) maList.GetObject( Min( mnPos, (long) nCount - 1L ) ); 422 423 if( pOut->GetConnectMetaFile() || ( pOut->GetOutDevType() == OUTDEV_PRINTER ) ) 424 ( (AnimationBitmap*) maList.GetObject( 0 ) )->aBmpEx.Draw( pOut, rDestPt, rDestSz ); 425 else if( ANIMATION_TIMEOUT_ON_CLICK == pObj->nWait ) 426 pObj->aBmpEx.Draw( pOut, rDestPt, rDestSz ); 427 else 428 { 429 const sal_uLong nOldPos = mnPos; 430 ( (Animation*) this )->mnPos = mbLoopTerminated ? ( nCount - 1UL ) : mnPos; 431 delete new ImplAnimView( (Animation*) this, pOut, rDestPt, rDestSz, 0 ); 432 ( (Animation*) this )->mnPos = nOldPos; 433 } 434 } 435 } 436 437 // ----------------------------------------------------------------------- 438 439 void Animation::ImplRestartTimer( sal_uLong nTimeout ) 440 { 441 maTimer.SetTimeout( Max( nTimeout, (sal_uLong)(MIN_TIMEOUT + ( mnAnimCount - 1 ) * INC_TIMEOUT) ) * 10L ); 442 maTimer.Start(); 443 } 444 445 // ----------------------------------------------------------------------- 446 447 IMPL_LINK( Animation, ImplTimeoutHdl, Timer*, EMPTYARG ) 448 { 449 const sal_uLong nAnimCount = maList.Count(); 450 451 if( nAnimCount ) 452 { 453 ImplAnimView* pView; 454 sal_Bool bGlobalPause = sal_True; 455 456 if( maNotifyLink.IsSet() ) 457 { 458 AInfo* pAInfo; 459 460 // create AInfo-List 461 for( pView = (ImplAnimView*) mpViewList->First(); pView; pView = (ImplAnimView*) mpViewList->Next() ) 462 maAInfoList.Insert( pView->ImplCreateAInfo() ); 463 464 maNotifyLink.Call( this ); 465 466 // set view state from AInfo structure 467 for( pAInfo = (AInfo*) maAInfoList.First(); pAInfo; pAInfo = (AInfo*) maAInfoList.Next() ) 468 { 469 if( !pAInfo->pViewData ) 470 { 471 pView = new ImplAnimView( this, pAInfo->pOutDev, 472 pAInfo->aStartOrg, pAInfo->aStartSize, pAInfo->nExtraData ); 473 474 mpViewList->Insert( pView, LIST_APPEND ); 475 } 476 else 477 pView = (ImplAnimView*) pAInfo->pViewData; 478 479 pView->ImplPause( pAInfo->bPause ); 480 pView->ImplSetMarked( sal_True ); 481 } 482 483 // delete AInfo structures 484 for( pAInfo = (AInfo*) maAInfoList.First(); pAInfo; pAInfo = (AInfo*) maAInfoList.Next() ) 485 delete (AInfo*) pAInfo; 486 maAInfoList.Clear(); 487 488 // delete all unmarked views and reset marked state 489 pView = (ImplAnimView*) mpViewList->First(); 490 while( pView ) 491 { 492 if( !pView->ImplIsMarked() ) 493 { 494 delete (ImplAnimView*) mpViewList->Remove( pView ); 495 pView = (ImplAnimView*) mpViewList->GetCurObject(); 496 } 497 else 498 { 499 if( !pView->ImplIsPause() ) 500 bGlobalPause = sal_False; 501 502 pView->ImplSetMarked( sal_False ); 503 pView = (ImplAnimView*) mpViewList->Next(); 504 } 505 } 506 } 507 else 508 bGlobalPause = sal_False; 509 510 if( !mpViewList->Count() ) 511 Stop(); 512 else if( bGlobalPause ) 513 ImplRestartTimer( 10 ); 514 else 515 { 516 AnimationBitmap* pStepBmp = (AnimationBitmap*) maList.GetObject( ++mnPos ); 517 518 if( !pStepBmp ) 519 { 520 if( mnLoops == 1 ) 521 { 522 Stop(); 523 mbLoopTerminated = sal_True; 524 mnPos = nAnimCount - 1UL; 525 maBitmapEx = ( (AnimationBitmap*) maList.GetObject( mnPos ) )->aBmpEx; 526 return 0L; 527 } 528 else 529 { 530 if( mnLoops ) 531 mnLoops--; 532 533 mnPos = 0; 534 pStepBmp = (AnimationBitmap*) maList.GetObject( mnPos ); 535 } 536 } 537 538 // Paint all views; after painting check, if view is 539 // marked; in this case remove view, because area of output 540 // lies out of display area of window; mark state is 541 // set from view itself 542 pView = (ImplAnimView*) mpViewList->First(); 543 while( pView ) 544 { 545 pView->ImplDraw( mnPos ); 546 547 if( pView->ImplIsMarked() ) 548 { 549 delete (ImplAnimView*) mpViewList->Remove( pView ); 550 pView = (ImplAnimView*) mpViewList->GetCurObject(); 551 } 552 else 553 pView = (ImplAnimView*) mpViewList->Next(); 554 } 555 556 // stop or restart timer 557 if( !mpViewList->Count() ) 558 Stop(); 559 else 560 ImplRestartTimer( pStepBmp->nWait ); 561 } 562 } 563 else 564 Stop(); 565 566 return 0L; 567 } 568 569 // ----------------------------------------------------------------------- 570 571 sal_Bool Animation::Insert( const AnimationBitmap& rStepBmp ) 572 { 573 sal_Bool bRet = sal_False; 574 575 if( !IsInAnimation() ) 576 { 577 Point aPoint; 578 Rectangle aGlobalRect( aPoint, maGlobalSize ); 579 580 maGlobalSize = aGlobalRect.Union( Rectangle( rStepBmp.aPosPix, rStepBmp.aSizePix ) ).GetSize(); 581 maList.Insert( new AnimationBitmap( rStepBmp ), LIST_APPEND ); 582 583 // zunaechst nehmen wir die erste BitmapEx als Ersatz-BitmapEx 584 if( maList.Count() == 1 ) 585 maBitmapEx = rStepBmp.aBmpEx; 586 587 bRet = sal_True; 588 } 589 590 return bRet; 591 } 592 593 // ----------------------------------------------------------------------- 594 595 const AnimationBitmap& Animation::Get( sal_uInt16 nAnimation ) const 596 { 597 DBG_ASSERT( ( nAnimation < maList.Count() ), "No object at this position" ); 598 return *(AnimationBitmap*) maList.GetObject( nAnimation ); 599 } 600 601 // ----------------------------------------------------------------------- 602 603 void Animation::Replace( const AnimationBitmap& rNewAnimationBitmap, sal_uInt16 nAnimation ) 604 { 605 DBG_ASSERT( ( nAnimation < maList.Count() ), "No object at this position" ); 606 607 delete (AnimationBitmap*) maList.Replace( new AnimationBitmap( rNewAnimationBitmap ), nAnimation ); 608 609 // Falls wir an erster Stelle einfuegen, 610 // muessen wir natuerlich auch, 611 // auch die Ersatzdarstellungs-BitmapEx 612 // aktualisieren; 613 if ( ( !nAnimation && ( !mbLoopTerminated || ( maList.Count() == 1 ) ) ) || 614 ( ( nAnimation == maList.Count() - 1 ) && mbLoopTerminated ) ) 615 { 616 maBitmapEx = rNewAnimationBitmap.aBmpEx; 617 } 618 } 619 620 // ----------------------------------------------------------------------- 621 622 void Animation::SetLoopCount( const sal_uLong nLoopCount ) 623 { 624 mnLoopCount = nLoopCount; 625 ResetLoopCount(); 626 } 627 628 // ----------------------------------------------------------------------- 629 630 void Animation::ResetLoopCount() 631 { 632 mnLoops = mnLoopCount; 633 mbLoopTerminated = sal_False; 634 } 635 636 // ----------------------------------------------------------------------- 637 638 sal_Bool Animation::Convert( BmpConversion eConversion ) 639 { 640 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); 641 642 sal_Bool bRet; 643 644 if( !IsInAnimation() && maList.Count() ) 645 { 646 bRet = sal_True; 647 648 for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) 649 bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Convert( eConversion ); 650 651 maBitmapEx.Convert( eConversion ); 652 } 653 else 654 bRet = sal_False; 655 656 return bRet; 657 } 658 659 // ----------------------------------------------------------------------- 660 661 sal_Bool Animation::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce ) 662 { 663 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); 664 665 sal_Bool bRet; 666 667 if( !IsInAnimation() && maList.Count() ) 668 { 669 bRet = sal_True; 670 671 for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) 672 bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.ReduceColors( nNewColorCount, eReduce ); 673 674 maBitmapEx.ReduceColors( nNewColorCount, eReduce ); 675 } 676 else 677 bRet = sal_False; 678 679 return bRet; 680 } 681 682 // ----------------------------------------------------------------------- 683 684 sal_Bool Animation::Invert() 685 { 686 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); 687 688 sal_Bool bRet; 689 690 if( !IsInAnimation() && maList.Count() ) 691 { 692 bRet = sal_True; 693 694 for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) 695 bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Invert(); 696 697 maBitmapEx.Invert(); 698 } 699 else 700 bRet = sal_False; 701 702 return bRet; 703 } 704 705 // ----------------------------------------------------------------------- 706 707 sal_Bool Animation::Mirror( sal_uLong nMirrorFlags ) 708 { 709 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); 710 711 sal_Bool bRet; 712 713 if( !IsInAnimation() && maList.Count() ) 714 { 715 bRet = sal_True; 716 717 if( nMirrorFlags ) 718 { 719 for( AnimationBitmap* pStepBmp = (AnimationBitmap*) maList.First(); 720 pStepBmp && bRet; 721 pStepBmp = (AnimationBitmap*) maList.Next() ) 722 { 723 if( ( bRet = pStepBmp->aBmpEx.Mirror( nMirrorFlags ) ) == sal_True ) 724 { 725 if( nMirrorFlags & BMP_MIRROR_HORZ ) 726 pStepBmp->aPosPix.X() = maGlobalSize.Width() - pStepBmp->aPosPix.X() - pStepBmp->aSizePix.Width(); 727 728 if( nMirrorFlags & BMP_MIRROR_VERT ) 729 pStepBmp->aPosPix.Y() = maGlobalSize.Height() - pStepBmp->aPosPix.Y() - pStepBmp->aSizePix.Height(); 730 } 731 } 732 733 maBitmapEx.Mirror( nMirrorFlags ); 734 } 735 } 736 else 737 bRet = sal_False; 738 739 return bRet; 740 } 741 742 // ----------------------------------------------------------------------- 743 744 sal_Bool Animation::Dither( sal_uLong nDitherFlags ) 745 { 746 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); 747 748 sal_Bool bRet; 749 750 if( !IsInAnimation() && maList.Count() ) 751 { 752 bRet = sal_True; 753 754 for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) 755 bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Dither( nDitherFlags ); 756 757 maBitmapEx.Dither( nDitherFlags ); 758 } 759 else 760 bRet = sal_False; 761 762 return bRet; 763 } 764 765 // ----------------------------------------------------------------------- 766 767 sal_Bool Animation::Adjust( short nLuminancePercent, short nContrastPercent, 768 short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, 769 double fGamma, sal_Bool bInvert ) 770 { 771 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); 772 773 sal_Bool bRet; 774 775 if( !IsInAnimation() && maList.Count() ) 776 { 777 bRet = sal_True; 778 779 for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) 780 { 781 bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Adjust( nLuminancePercent, nContrastPercent, 782 nChannelRPercent, nChannelGPercent, nChannelBPercent, 783 fGamma, bInvert ); 784 } 785 786 maBitmapEx.Adjust( nLuminancePercent, nContrastPercent, 787 nChannelRPercent, nChannelGPercent, nChannelBPercent, 788 fGamma, bInvert ); 789 } 790 else 791 bRet = sal_False; 792 793 return bRet; 794 } 795 796 // ----------------------------------------------------------------------- 797 798 sal_Bool Animation::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress ) 799 { 800 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); 801 802 sal_Bool bRet; 803 804 if( !IsInAnimation() && maList.Count() ) 805 { 806 bRet = sal_True; 807 808 for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) 809 bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Filter( eFilter, pFilterParam, pProgress ); 810 811 maBitmapEx.Filter( eFilter, pFilterParam, pProgress ); 812 } 813 else 814 bRet = sal_False; 815 816 return bRet; 817 } 818 819 // ----------------------------------------------------------------------- 820 821 SvStream& operator<<( SvStream& rOStm, const Animation& rAnimation ) 822 { 823 const sal_uInt16 nCount = rAnimation.Count(); 824 825 if( nCount ) 826 { 827 const ByteString aDummyStr; 828 const sal_uInt32 nDummy32 = 0UL; 829 830 // Falls keine BitmapEx gesetzt wurde, schreiben wir 831 // einfach die erste Bitmap der Animation 832 if( !rAnimation.GetBitmapEx().GetBitmap() ) 833 rOStm << rAnimation.Get( 0 ).aBmpEx; 834 else 835 rOStm << rAnimation.GetBitmapEx(); 836 837 // Kennung schreiben ( SDANIMA1 ) 838 rOStm << (sal_uInt32) 0x5344414e << (sal_uInt32) 0x494d4931; 839 840 for( sal_uInt16 i = 0; i < nCount; i++ ) 841 { 842 const AnimationBitmap& rAnimBmp = rAnimation.Get( i ); 843 const sal_uInt16 nRest = nCount - i - 1; 844 845 // AnimationBitmap schreiben 846 rOStm << rAnimBmp.aBmpEx; 847 rOStm << rAnimBmp.aPosPix; 848 rOStm << rAnimBmp.aSizePix; 849 rOStm << rAnimation.maGlobalSize; 850 rOStm << (sal_uInt16) ( ( ANIMATION_TIMEOUT_ON_CLICK == rAnimBmp.nWait ) ? 65535 : rAnimBmp.nWait ); 851 rOStm << (sal_uInt16) rAnimBmp.eDisposal; 852 rOStm << (sal_uInt8) rAnimBmp.bUserInput; 853 rOStm << (sal_uInt32) rAnimation.mnLoopCount; 854 rOStm << nDummy32; // unbenutzt 855 rOStm << nDummy32; // unbenutzt 856 rOStm << nDummy32; // unbenutzt 857 rOStm << aDummyStr; // unbenutzt 858 rOStm << nRest; // Anzahl der Strukturen, die noch _folgen_ 859 } 860 } 861 862 return rOStm; 863 } 864 865 // ----------------------------------------------------------------------- 866 867 SvStream& operator>>( SvStream& rIStm, Animation& rAnimation ) 868 { 869 Bitmap aBmp; 870 sal_uLong nStmPos = rIStm.Tell(); 871 sal_uInt32 nAnimMagic1, nAnimMagic2; 872 sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); 873 sal_Bool bReadAnimations = sal_False; 874 875 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 876 nStmPos = rIStm.Tell(); 877 rIStm >> nAnimMagic1 >> nAnimMagic2; 878 879 rAnimation.Clear(); 880 881 // Wenn die BitmapEx am Anfang schon gelesen 882 // wurde ( von Graphic ), koennen wir direkt die Animationsbitmaps einlesen 883 if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() ) 884 bReadAnimations = sal_True; 885 // ansonsten versuchen wir erstmal die Bitmap(-Ex) zu lesen 886 else 887 { 888 rIStm.Seek( nStmPos ); 889 rIStm >> rAnimation.maBitmapEx; 890 nStmPos = rIStm.Tell(); 891 rIStm >> nAnimMagic1 >> nAnimMagic2; 892 893 if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() ) 894 bReadAnimations = sal_True; 895 else 896 rIStm.Seek( nStmPos ); 897 } 898 899 // ggf. Animationsbitmaps lesen 900 if( bReadAnimations ) 901 { 902 AnimationBitmap aAnimBmp; 903 BitmapEx aBmpEx; 904 ByteString aDummyStr; 905 sal_uInt32 nTmp32; 906 sal_uInt16 nTmp16; 907 sal_uInt8 cTmp; 908 909 do 910 { 911 rIStm >> aAnimBmp.aBmpEx; 912 rIStm >> aAnimBmp.aPosPix; 913 rIStm >> aAnimBmp.aSizePix; 914 rIStm >> rAnimation.maGlobalSize; 915 rIStm >> nTmp16; aAnimBmp.nWait = ( ( 65535 == nTmp16 ) ? ANIMATION_TIMEOUT_ON_CLICK : nTmp16 ); 916 rIStm >> nTmp16; aAnimBmp.eDisposal = ( Disposal) nTmp16; 917 rIStm >> cTmp; aAnimBmp.bUserInput = (sal_Bool) cTmp; 918 rIStm >> nTmp32; rAnimation.mnLoopCount = (sal_uInt16) nTmp32; 919 rIStm >> nTmp32; // unbenutzt 920 rIStm >> nTmp32; // unbenutzt 921 rIStm >> nTmp32; // unbenutzt 922 rIStm >> aDummyStr; // unbenutzt 923 rIStm >> nTmp16; // Rest zu lesen 924 925 rAnimation.Insert( aAnimBmp ); 926 } 927 while( nTmp16 && !rIStm.GetError() ); 928 929 rAnimation.ResetLoopCount(); 930 } 931 932 rIStm.SetNumberFormatInt( nOldFormat ); 933 934 return rIStm; 935 } 936