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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_vcl.hxx" 24 25 #include <ctype.h> 26 #include <rtl/crc.h> 27 #include <tools/stream.hxx> 28 #include <tools/debug.hxx> 29 #include <tools/rc.h> 30 #include <vcl/salbtype.hxx> 31 #include <vcl/outdev.hxx> 32 #include <vcl/alpha.hxx> 33 #include <vcl/bitmapex.hxx> 34 #include <vcl/pngread.hxx> 35 #include <vcl/svapp.hxx> 36 #include <vcl/bmpacc.hxx> 37 #include <vcl/dibtools.hxx> 38 #include <image.h> 39 #include <impimagetree.hxx> 40 41 // ------------ 42 // - BitmapEx - 43 // ------------ 44 45 BitmapEx::BitmapEx() : 46 eTransparent( TRANSPARENT_NONE ), 47 bAlpha ( sal_False ) 48 { 49 } 50 51 // ------------------------------------------------------------------ 52 53 BitmapEx::BitmapEx( const BitmapEx& rBitmapEx ) : 54 aBitmap ( rBitmapEx.aBitmap ), 55 aMask ( rBitmapEx.aMask ), 56 aBitmapSize ( rBitmapEx.aBitmapSize ), 57 aTransparentColor ( rBitmapEx.aTransparentColor ), 58 eTransparent ( rBitmapEx.eTransparent ), 59 bAlpha ( rBitmapEx.bAlpha ) 60 { 61 } 62 63 BitmapEx::BitmapEx( const BitmapEx& rBitmapEx, Point aSrc, Size aSize ) : 64 eTransparent( TRANSPARENT_NONE ), 65 bAlpha ( sal_False ) 66 { 67 if( rBitmapEx.IsEmpty() ) 68 return; 69 70 aBitmap = Bitmap( aSize, rBitmapEx.aBitmap.GetBitCount() ); 71 aBitmapSize = aSize; 72 if( rBitmapEx.IsAlpha() ) 73 { 74 bAlpha = sal_True; 75 aMask = AlphaMask( aSize ).ImplGetBitmap(); 76 } 77 else if( rBitmapEx.IsTransparent() ) 78 aMask = Bitmap( aSize, rBitmapEx.aMask.GetBitCount() ); 79 80 Rectangle aDestRect( Point( 0, 0 ), aSize ); 81 Rectangle aSrcRect( aSrc, aSize ); 82 CopyPixel( aDestRect, aSrcRect, &rBitmapEx ); 83 } 84 85 // ------------------------------------------------------------------ 86 87 BitmapEx::BitmapEx( const ResId& rResId ) : 88 eTransparent( TRANSPARENT_NONE ), 89 bAlpha ( sal_False ) 90 { 91 static ImplImageTreeSingletonRef aImageTree; 92 ResMgr* pResMgr = NULL; 93 94 ResMgr::GetResourceSkipHeader( rResId.SetRT( RSC_BITMAP ), &pResMgr ); 95 pResMgr->ReadLong(); 96 pResMgr->ReadLong(); 97 98 const String aFileName( pResMgr->ReadString() ); 99 ::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName(); 100 101 if( !aImageTree->loadImage( aFileName, aCurrentSymbolsStyle, *this ) ) 102 { 103 #ifdef DBG_UTIL 104 ByteString aErrorStr( "BitmapEx::BitmapEx( const ResId& rResId ): could not load image <" ); 105 DBG_ERROR( ( ( aErrorStr += ByteString( aFileName, RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() ); 106 #endif 107 } 108 } 109 110 // ------------------------------------------------------------------ 111 112 BitmapEx::BitmapEx( const Bitmap& rBmp ) : 113 aBitmap ( rBmp ), 114 aBitmapSize ( aBitmap.GetSizePixel() ), 115 eTransparent( TRANSPARENT_NONE ), 116 bAlpha ( sal_False ) 117 { 118 } 119 120 // ------------------------------------------------------------------ 121 122 BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) : 123 aBitmap ( rBmp ), 124 aMask ( rMask ), 125 aBitmapSize ( aBitmap.GetSizePixel() ), 126 eTransparent ( !rMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ), 127 bAlpha ( sal_False ) 128 { 129 if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel()) 130 { 131 OSL_ENSURE(false, "Mask size differs from Bitmap size, corrected Mask (!)"); 132 aMask.Scale(aBitmap.GetSizePixel()); 133 } 134 135 // #105489# Ensure a mask is exactly one bit deep 136 if( !!aMask && aMask.GetBitCount() != 1 ) 137 { 138 OSL_TRACE("BitmapEx: forced mask to monochrome"); 139 aMask.ImplMakeMono( 255 ); 140 } 141 } 142 143 // ------------------------------------------------------------------ 144 145 BitmapEx::BitmapEx( const Bitmap& rBmp, const AlphaMask& rAlphaMask ) : 146 aBitmap ( rBmp ), 147 aMask ( rAlphaMask.ImplGetBitmap() ), 148 aBitmapSize ( aBitmap.GetSizePixel() ), 149 eTransparent ( !rAlphaMask ? TRANSPARENT_NONE : TRANSPARENT_BITMAP ), 150 bAlpha ( !rAlphaMask ? sal_False : sal_True ) 151 { 152 if(!!aBitmap && !!aMask && aBitmap.GetSizePixel() != aMask.GetSizePixel()) 153 { 154 OSL_ENSURE(false, "Alpha size differs from Bitmap size, corrected Mask (!)"); 155 aMask.Scale(rBmp.GetSizePixel()); 156 } 157 158 // #i75531# the workaround below can go when 159 // X11SalGraphics::drawAlphaBitmap()'s render acceleration 160 // can handle the bitmap depth mismatch directly 161 if( aBitmap.GetBitCount() < aMask.GetBitCount() ) 162 aBitmap.Convert( BMP_CONVERSION_24BIT ); 163 } 164 165 // ------------------------------------------------------------------ 166 167 BitmapEx::BitmapEx( const Bitmap& rBmp, const Color& rTransparentColor ) : 168 aBitmap ( rBmp ), 169 aBitmapSize ( aBitmap.GetSizePixel() ), 170 aTransparentColor ( rTransparentColor ), 171 eTransparent ( TRANSPARENT_BITMAP ), 172 bAlpha ( sal_False ) 173 { 174 aMask = aBitmap.CreateMask( aTransparentColor ); 175 176 DBG_ASSERT( rBmp.GetSizePixel() == aMask.GetSizePixel(), 177 "BitmapEx::BitmapEx(): size mismatch for bitmap and alpha mask." ); 178 } 179 180 // ------------------------------------------------------------------ 181 182 BitmapEx::~BitmapEx() 183 { 184 } 185 186 // ------------------------------------------------------------------ 187 188 // ------------------------------------------------------------------ 189 190 BitmapEx& BitmapEx::operator=( const BitmapEx& rBitmapEx ) 191 { 192 if( &rBitmapEx != this ) 193 { 194 aBitmap = rBitmapEx.aBitmap; 195 aMask = rBitmapEx.aMask; 196 aBitmapSize = rBitmapEx.aBitmapSize; 197 aTransparentColor = rBitmapEx.aTransparentColor; 198 eTransparent = rBitmapEx.eTransparent; 199 bAlpha = rBitmapEx.bAlpha; 200 } 201 202 return *this; 203 } 204 205 // ------------------------------------------------------------------ 206 207 sal_Bool BitmapEx::operator==( const BitmapEx& rBitmapEx ) const 208 { 209 if( eTransparent != rBitmapEx.eTransparent ) 210 return sal_False; 211 212 if( aBitmap != rBitmapEx.aBitmap ) 213 return sal_False; 214 215 if( aBitmapSize != rBitmapEx.aBitmapSize ) 216 return sal_False; 217 218 if( eTransparent == TRANSPARENT_NONE ) 219 return sal_True; 220 221 if( eTransparent == TRANSPARENT_COLOR ) 222 return aTransparentColor == rBitmapEx.aTransparentColor; 223 224 return( ( aMask == rBitmapEx.aMask ) && ( bAlpha == rBitmapEx.bAlpha ) ); 225 } 226 227 // ------------------------------------------------------------------ 228 229 sal_Bool BitmapEx::IsEqual( const BitmapEx& rBmpEx ) const 230 { 231 return( rBmpEx.eTransparent == eTransparent && 232 rBmpEx.bAlpha == bAlpha && 233 rBmpEx.aBitmap.IsEqual( aBitmap ) && 234 rBmpEx.aMask.IsEqual( aMask ) ); 235 } 236 237 // ------------------------------------------------------------------ 238 239 sal_Bool BitmapEx::IsEmpty() const 240 { 241 return( aBitmap.IsEmpty() && aMask.IsEmpty() ); 242 } 243 244 // ------------------------------------------------------------------ 245 246 void BitmapEx::SetEmpty() 247 { 248 aBitmap.SetEmpty(); 249 aMask.SetEmpty(); 250 eTransparent = TRANSPARENT_NONE; 251 bAlpha = sal_False; 252 } 253 254 // ------------------------------------------------------------------ 255 256 void BitmapEx::Clear() 257 { 258 SetEmpty(); 259 } 260 261 // ------------------------------------------------------------------ 262 263 sal_Bool BitmapEx::IsTransparent() const 264 { 265 return( eTransparent != TRANSPARENT_NONE ); 266 } 267 268 // ------------------------------------------------------------------ 269 270 sal_Bool BitmapEx::IsAlpha() const 271 { 272 return( IsTransparent() && bAlpha ); 273 } 274 275 // ------------------------------------------------------------------ 276 277 Bitmap BitmapEx::GetBitmap( const Color* pTransReplaceColor ) const 278 { 279 Bitmap aRetBmp( aBitmap ); 280 281 if( pTransReplaceColor && ( eTransparent != TRANSPARENT_NONE ) ) 282 { 283 Bitmap aTempMask; 284 285 if( eTransparent == TRANSPARENT_COLOR ) 286 aTempMask = aBitmap.CreateMask( aTransparentColor ); 287 else 288 aTempMask = aMask; 289 290 if( !IsAlpha() ) 291 aRetBmp.Replace( aTempMask, *pTransReplaceColor ); 292 else 293 aRetBmp.Replace( GetAlpha(), *pTransReplaceColor ); 294 } 295 296 return aRetBmp; 297 } 298 299 // ------------------------------------------------------------------ 300 301 BitmapEx BitmapEx::GetColorTransformedBitmapEx( BmpColorMode eColorMode ) const 302 { 303 BitmapEx aRet; 304 305 if( BMP_COLOR_HIGHCONTRAST == eColorMode ) 306 { 307 aRet = *this; 308 aRet.aBitmap = aBitmap.GetColorTransformedBitmap( eColorMode ); 309 } 310 else if( BMP_COLOR_MONOCHROME_BLACK == eColorMode || 311 BMP_COLOR_MONOCHROME_WHITE == eColorMode ) 312 { 313 aRet = *this; 314 aRet.aBitmap = aRet.aBitmap.GetColorTransformedBitmap( eColorMode ); 315 316 if( !aRet.aMask.IsEmpty() ) 317 { 318 aRet.aMask.CombineSimple( aRet.aBitmap, BMP_COMBINE_OR ); 319 aRet.aBitmap.Erase( ( BMP_COLOR_MONOCHROME_BLACK == eColorMode ) ? COL_BLACK : COL_WHITE ); 320 321 DBG_ASSERT( aRet.aBitmap.GetSizePixel() == aRet.aMask.GetSizePixel(), 322 "BitmapEx::GetColorTransformedBitmapEx(): size mismatch for bitmap and alpha mask." ); 323 } 324 } 325 326 return aRet; 327 } 328 329 // ------------------------------------------------------------------ 330 331 Bitmap BitmapEx::GetMask() const 332 { 333 Bitmap aRet( aMask ); 334 335 if( IsAlpha() ) 336 aRet.ImplMakeMono( 255 ); 337 338 return aRet; 339 } 340 341 // ------------------------------------------------------------------ 342 343 AlphaMask BitmapEx::GetAlpha() const 344 { 345 AlphaMask aAlpha; 346 347 if( IsAlpha() ) 348 aAlpha.ImplSetBitmap( aMask ); 349 else 350 aAlpha = aMask; 351 352 return aAlpha; 353 } 354 355 // ------------------------------------------------------------------ 356 357 sal_uLong BitmapEx::GetSizeBytes() const 358 { 359 sal_uLong nSizeBytes = aBitmap.GetSizeBytes(); 360 361 if( eTransparent == TRANSPARENT_BITMAP ) 362 nSizeBytes += aMask.GetSizeBytes(); 363 364 return nSizeBytes; 365 } 366 367 // ------------------------------------------------------------------ 368 369 sal_uLong BitmapEx::GetChecksum() const 370 { 371 sal_uInt32 nCrc = aBitmap.GetChecksum(); 372 SVBT32 aBT32; 373 374 UInt32ToSVBT32( (long) eTransparent, aBT32 ); 375 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 376 377 UInt32ToSVBT32( (long) bAlpha, aBT32 ); 378 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 379 380 if( ( TRANSPARENT_BITMAP == eTransparent ) && !aMask.IsEmpty() ) 381 { 382 UInt32ToSVBT32( aMask.GetChecksum(), aBT32 ); 383 nCrc = rtl_crc32( nCrc, aBT32, 4 ); 384 } 385 386 return nCrc; 387 } 388 389 // ------------------------------------------------------------------ 390 391 void BitmapEx::SetSizePixel( const Size& rNewSize, sal_uInt32 nScaleFlag ) 392 { 393 if(GetSizePixel() != rNewSize) 394 { 395 Scale( rNewSize, nScaleFlag ); 396 } 397 } 398 399 // ------------------------------------------------------------------ 400 401 sal_Bool BitmapEx::Invert() 402 { 403 sal_Bool bRet = sal_False; 404 405 if( !!aBitmap ) 406 { 407 bRet = aBitmap.Invert(); 408 409 if( bRet && ( eTransparent == TRANSPARENT_COLOR ) ) 410 aTransparentColor = BitmapColor( aTransparentColor ).Invert(); 411 } 412 413 return bRet; 414 } 415 416 // ------------------------------------------------------------------ 417 418 sal_Bool BitmapEx::Mirror( sal_uLong nMirrorFlags ) 419 { 420 sal_Bool bRet = sal_False; 421 422 if( !!aBitmap ) 423 { 424 bRet = aBitmap.Mirror( nMirrorFlags ); 425 426 if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 427 aMask.Mirror( nMirrorFlags ); 428 } 429 430 return bRet; 431 } 432 433 // ------------------------------------------------------------------ 434 435 sal_Bool BitmapEx::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag ) 436 { 437 sal_Bool bRet = sal_False; 438 439 if( !!aBitmap ) 440 { 441 bRet = aBitmap.Scale( rScaleX, rScaleY, nScaleFlag ); 442 443 if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 444 { 445 aMask.Scale( rScaleX, rScaleY, nScaleFlag ); 446 } 447 448 aBitmapSize = aBitmap.GetSizePixel(); 449 450 DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 451 "BitmapEx::Scale(): size mismatch for bitmap and alpha mask." ); 452 } 453 454 return bRet; 455 } 456 457 // ------------------------------------------------------------------------ 458 459 sal_Bool BitmapEx::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag ) 460 { 461 sal_Bool bRet; 462 463 if( aBitmapSize.Width() && aBitmapSize.Height() ) 464 { 465 bRet = Scale( (double) rNewSize.Width() / aBitmapSize.Width(), 466 (double) rNewSize.Height() / aBitmapSize.Height(), 467 nScaleFlag ); 468 } 469 else 470 bRet = sal_True; 471 472 return bRet; 473 } 474 475 // ------------------------------------------------------------------ 476 477 sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor ) 478 { 479 sal_Bool bRet = sal_False; 480 481 if( !!aBitmap ) 482 { 483 const sal_Bool bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor ); 484 485 if( bTransRotate ) 486 { 487 if( eTransparent == TRANSPARENT_COLOR ) 488 bRet = aBitmap.Rotate( nAngle10, aTransparentColor ); 489 else 490 { 491 bRet = aBitmap.Rotate( nAngle10, COL_BLACK ); 492 493 if( eTransparent == TRANSPARENT_NONE ) 494 { 495 aMask = Bitmap( aBitmapSize, 1 ); 496 aMask.Erase( COL_BLACK ); 497 eTransparent = TRANSPARENT_BITMAP; 498 } 499 500 if( bRet && !!aMask ) 501 aMask.Rotate( nAngle10, COL_WHITE ); 502 } 503 } 504 else 505 { 506 bRet = aBitmap.Rotate( nAngle10, rFillColor ); 507 508 if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 509 aMask.Rotate( nAngle10, COL_WHITE ); 510 } 511 512 aBitmapSize = aBitmap.GetSizePixel(); 513 514 DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 515 "BitmapEx::Rotate(): size mismatch for bitmap and alpha mask." ); 516 } 517 518 return bRet; 519 } 520 521 // ------------------------------------------------------------------ 522 523 sal_Bool BitmapEx::Crop( const Rectangle& rRectPixel ) 524 { 525 sal_Bool bRet = sal_False; 526 527 if( !!aBitmap ) 528 { 529 bRet = aBitmap.Crop( rRectPixel ); 530 531 if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 532 aMask.Crop( rRectPixel ); 533 534 aBitmapSize = aBitmap.GetSizePixel(); 535 536 DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 537 "BitmapEx::Crop(): size mismatch for bitmap and alpha mask." ); 538 } 539 540 return bRet; 541 } 542 543 // ------------------------------------------------------------------ 544 545 sal_Bool BitmapEx::Convert( BmpConversion eConversion ) 546 { 547 return( !!aBitmap ? aBitmap.Convert( eConversion ) : sal_False ); 548 } 549 550 // ------------------------------------------------------------------ 551 552 sal_Bool BitmapEx::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce ) 553 { 554 return( !!aBitmap ? aBitmap.ReduceColors( nNewColorCount, eReduce ) : sal_False ); 555 } 556 557 // ------------------------------------------------------------------ 558 559 sal_Bool BitmapEx::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor, sal_Bool bExpandTransparent ) 560 { 561 sal_Bool bRet = sal_False; 562 563 if( !!aBitmap ) 564 { 565 bRet = aBitmap.Expand( nDX, nDY, pInitColor ); 566 567 if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 568 { 569 Color aColor( bExpandTransparent ? COL_WHITE : COL_BLACK ); 570 aMask.Expand( nDX, nDY, &aColor ); 571 } 572 573 aBitmapSize = aBitmap.GetSizePixel(); 574 575 DBG_ASSERT( !aMask || aBitmap.GetSizePixel() == aMask.GetSizePixel(), 576 "BitmapEx::Expand(): size mismatch for bitmap and alpha mask." ); 577 } 578 579 return bRet; 580 } 581 582 // ------------------------------------------------------------------ 583 584 sal_Bool BitmapEx::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc, 585 const BitmapEx* pBmpExSrc ) 586 { 587 sal_Bool bRet = sal_False; 588 589 if( !pBmpExSrc || pBmpExSrc->IsEmpty() ) 590 { 591 if( !aBitmap.IsEmpty() ) 592 { 593 bRet = aBitmap.CopyPixel( rRectDst, rRectSrc ); 594 595 if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 596 aMask.CopyPixel( rRectDst, rRectSrc ); 597 } 598 } 599 else 600 { 601 if( !aBitmap.IsEmpty() ) 602 { 603 bRet = aBitmap.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aBitmap ); 604 605 if( bRet ) 606 { 607 if( pBmpExSrc->IsAlpha() ) 608 { 609 if( IsAlpha() ) 610 // cast to use the optimized AlphaMask::CopyPixel 611 ((AlphaMask*) &aMask)->CopyPixel( rRectDst, rRectSrc, (AlphaMask*)&pBmpExSrc->aMask ); 612 else if( IsTransparent() ) 613 { 614 AlphaMask* pAlpha = new AlphaMask( aMask ); 615 616 aMask = pAlpha->ImplGetBitmap(); 617 delete pAlpha; 618 bAlpha = sal_True; 619 aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 620 } 621 else 622 { 623 sal_uInt8 cBlack = 0; 624 AlphaMask* pAlpha = new AlphaMask( GetSizePixel(), &cBlack ); 625 626 aMask = pAlpha->ImplGetBitmap(); 627 delete pAlpha; 628 eTransparent = TRANSPARENT_BITMAP; 629 bAlpha = sal_True; 630 aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 631 } 632 } 633 else if( pBmpExSrc->IsTransparent() ) 634 { 635 if( IsAlpha() ) 636 { 637 AlphaMask aAlpha( pBmpExSrc->aMask ); 638 aMask.CopyPixel( rRectDst, rRectSrc, &aAlpha.ImplGetBitmap() ); 639 } 640 else if( IsTransparent() ) 641 aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 642 else 643 { 644 aMask = Bitmap( GetSizePixel(), 1 ); 645 aMask.Erase( Color( COL_BLACK ) ); 646 eTransparent = TRANSPARENT_BITMAP; 647 aMask.CopyPixel( rRectDst, rRectSrc, &pBmpExSrc->aMask ); 648 } 649 } 650 else if( IsAlpha() ) 651 { 652 sal_uInt8 cBlack = 0; 653 const AlphaMask aAlphaSrc( pBmpExSrc->GetSizePixel(), &cBlack ); 654 655 aMask.CopyPixel( rRectDst, rRectSrc, &aAlphaSrc.ImplGetBitmap() ); 656 } 657 else if( IsTransparent() ) 658 { 659 Bitmap aMaskSrc( pBmpExSrc->GetSizePixel(), 1 ); 660 661 aMaskSrc.Erase( Color( COL_BLACK ) ); 662 aMask.CopyPixel( rRectDst, rRectSrc, &aMaskSrc ); 663 } 664 } 665 } 666 } 667 668 return bRet; 669 } 670 671 // ------------------------------------------------------------------ 672 673 sal_Bool BitmapEx::Erase( const Color& rFillColor ) 674 { 675 sal_Bool bRet = sal_False; 676 677 if( !!aBitmap ) 678 { 679 bRet = aBitmap.Erase( rFillColor ); 680 681 if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask ) 682 { 683 // #104416# Respect transparency on fill color 684 if( rFillColor.GetTransparency() ) 685 { 686 const Color aFill( rFillColor.GetTransparency(), rFillColor.GetTransparency(), rFillColor.GetTransparency() ); 687 aMask.Erase( aFill ); 688 } 689 else 690 { 691 const Color aBlack( COL_BLACK ); 692 aMask.Erase( aBlack ); 693 } 694 } 695 } 696 697 return bRet; 698 } 699 700 // ------------------------------------------------------------------ 701 702 sal_Bool BitmapEx::Dither( sal_uLong nDitherFlags ) 703 { 704 return( !!aBitmap ? aBitmap.Dither( nDitherFlags ) : sal_False ); 705 } 706 707 // ------------------------------------------------------------------ 708 709 sal_Bool BitmapEx::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol ) 710 { 711 return( !!aBitmap ? aBitmap.Replace( rSearchColor, rReplaceColor, nTol ) : sal_False ); 712 } 713 714 // ------------------------------------------------------------------ 715 716 sal_Bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, const sal_uLong* pTols ) 717 { 718 return( !!aBitmap ? aBitmap.Replace( pSearchColors, pReplaceColors, nColorCount, (sal_uLong*) pTols ) : sal_False ); 719 } 720 721 // ------------------------------------------------------------------ 722 723 sal_Bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent, 724 short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, 725 double fGamma, sal_Bool bInvert ) 726 { 727 return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent, 728 nChannelRPercent, nChannelGPercent, nChannelBPercent, 729 fGamma, bInvert ) : sal_False ); 730 } 731 732 // ------------------------------------------------------------------ 733 734 sal_Bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress ) 735 { 736 return( !!aBitmap ? aBitmap.Filter( eFilter, pFilterParam, pProgress ) : sal_False ); 737 } 738 739 // ------------------------------------------------------------------ 740 741 void BitmapEx::Draw( OutputDevice* pOutDev, const Point& rDestPt ) const 742 { 743 pOutDev->DrawBitmapEx( rDestPt, *this ); 744 } 745 746 // ------------------------------------------------------------------ 747 748 void BitmapEx::Draw( OutputDevice* pOutDev, 749 const Point& rDestPt, const Size& rDestSize ) const 750 { 751 pOutDev->DrawBitmapEx( rDestPt, rDestSize, *this ); 752 } 753 754 // ------------------------------------------------------------------ 755 756 void BitmapEx::Draw( OutputDevice* pOutDev, 757 const Point& rDestPt, const Size& rDestSize, 758 const Point& rSrcPtPixel, const Size& rSrcSizePixel ) const 759 { 760 pOutDev->DrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, *this ); 761 } 762 763 // ------------------------------------------------------------------ 764 765 sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const 766 { 767 sal_uInt8 nTransparency(0xff); 768 769 if(!aBitmap.IsEmpty()) 770 { 771 if(nX >= 0 && nX < aBitmapSize.Width() && nY >= 0 && nY < aBitmapSize.Height()) 772 { 773 switch(eTransparent) 774 { 775 case TRANSPARENT_NONE: 776 { 777 // not transparent, ergo all covered 778 nTransparency = 0x00; 779 break; 780 } 781 case TRANSPARENT_COLOR: 782 { 783 Bitmap aTestBitmap(aBitmap); 784 BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess(); 785 786 if(pRead) 787 { 788 const Color aColor = pRead->GetColor(nY, nX); 789 790 // if color is not equal to TransparentColor, we are not transparent 791 if(aColor != aTransparentColor) 792 { 793 nTransparency = 0x00; 794 } 795 796 aTestBitmap.ReleaseAccess(pRead); 797 } 798 break; 799 } 800 case TRANSPARENT_BITMAP: 801 { 802 if(!aMask.IsEmpty()) 803 { 804 Bitmap aTestBitmap(aMask); 805 BitmapReadAccess* pRead = aTestBitmap.AcquireReadAccess(); 806 807 if(pRead) 808 { 809 const BitmapColor aBitmapColor(pRead->GetPixel(nY, nX)); 810 811 if(bAlpha) 812 { 813 nTransparency = aBitmapColor.GetIndex(); 814 } 815 else 816 { 817 if(0x00 == aBitmapColor.GetIndex()) 818 { 819 nTransparency = 0x00; 820 } 821 } 822 823 aTestBitmap.ReleaseAccess(pRead); 824 } 825 } 826 break; 827 } 828 } 829 } 830 } 831 832 return nTransparency; 833 } 834 835 // ------------------------------------------------------------------ 836 // eof 837