1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <bmpfast.hxx> 32 33 #ifndef NO_OPTIMIZED_BITMAP_ACCESS 34 35 #include <tools/debug.hxx> 36 #include <vcl/bmpacc.hxx> 37 38 #define FAST_ARGB_BGRA 39 40 #include <stdlib.h> 41 static bool bDisableFastBitops = (getenv( "SAL_DISABLE_BITMAPS_OPTS" ) != NULL); 42 43 typedef unsigned char PIXBYTE; 44 45 class BasePixelPtr 46 { 47 public: 48 BasePixelPtr( PIXBYTE* p = NULL ) : mpPixel( p ) {} 49 void SetRawPtr( PIXBYTE* pRawPtr ) { mpPixel = pRawPtr; } 50 PIXBYTE* GetRawPtr( void ) const { return mpPixel; } 51 void AddByteOffset( int nByteOffset ) { mpPixel += nByteOffset; } 52 bool operator<( const BasePixelPtr& rCmp ) const { return (mpPixel < rCmp.mpPixel); } 53 54 protected: 55 PIXBYTE* mpPixel; 56 }; 57 58 template <sal_uLong PIXFMT> 59 class TrueColorPixelPtr : public BasePixelPtr 60 { 61 public: 62 PIXBYTE GetRed() const; 63 PIXBYTE GetGreen() const; 64 PIXBYTE GetBlue() const; 65 PIXBYTE GetAlpha() const; 66 67 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const; 68 void SetAlpha( PIXBYTE a ) const; 69 void operator++(int); 70 }; 71 72 // ======================================================================= 73 // template specializations for truecolor pixel formats 74 75 template <> 76 class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_RGB> : public BasePixelPtr 77 { 78 public: 79 void operator++() { mpPixel += 3; } 80 81 PIXBYTE GetRed() const { return mpPixel[0]; } 82 PIXBYTE GetGreen() const { return mpPixel[1]; } 83 PIXBYTE GetBlue() const { return mpPixel[2]; } 84 PIXBYTE GetAlpha() const { return 0; } 85 void SetAlpha( PIXBYTE ) const {} 86 87 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 88 { 89 mpPixel[0] = r; 90 mpPixel[1] = g; 91 mpPixel[2] = b; 92 } 93 }; 94 95 template <> 96 class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_BGR> : public BasePixelPtr 97 { 98 public: 99 void operator++() { mpPixel += 3; } 100 101 PIXBYTE GetRed() const { return mpPixel[2]; } 102 PIXBYTE GetGreen() const { return mpPixel[1]; } 103 PIXBYTE GetBlue() const { return mpPixel[0]; } 104 PIXBYTE GetAlpha() const { return 0; } 105 void SetAlpha( PIXBYTE ) const {} 106 107 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 108 { 109 mpPixel[0] = b; 110 mpPixel[1] = g; 111 mpPixel[2] = r; 112 } 113 }; 114 115 template <> 116 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ARGB> : public BasePixelPtr 117 { 118 public: 119 void operator++() { mpPixel += 4; } 120 121 PIXBYTE GetRed() const { return mpPixel[1]; } 122 PIXBYTE GetGreen() const { return mpPixel[2]; } 123 PIXBYTE GetBlue() const { return mpPixel[3]; } 124 PIXBYTE GetAlpha() const { return mpPixel[0]; } 125 void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; } 126 127 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 128 { 129 mpPixel[1] = r; 130 mpPixel[2] = g; 131 mpPixel[3] = b; 132 } 133 }; 134 135 template <> 136 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ABGR> : public BasePixelPtr 137 { 138 public: 139 void operator++() { mpPixel += 4; } 140 141 PIXBYTE GetRed() const { return mpPixel[3]; } 142 PIXBYTE GetGreen() const { return mpPixel[2]; } 143 PIXBYTE GetBlue() const { return mpPixel[1]; } 144 PIXBYTE GetAlpha() const { return mpPixel[0]; } 145 void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; } 146 147 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 148 { 149 mpPixel[1] = b; 150 mpPixel[2] = g; 151 mpPixel[3] = r; 152 } 153 }; 154 155 template <> 156 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_RGBA> : public BasePixelPtr 157 { 158 public: 159 void operator++() { mpPixel += 4; } 160 161 PIXBYTE GetRed() const { return mpPixel[0]; } 162 PIXBYTE GetGreen() const { return mpPixel[1]; } 163 PIXBYTE GetBlue() const { return mpPixel[2]; } 164 PIXBYTE GetAlpha() const { return mpPixel[3]; } 165 void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; } 166 167 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 168 { 169 mpPixel[0] = r; 170 mpPixel[1] = g; 171 mpPixel[2] = b; 172 } 173 }; 174 175 template <> 176 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_BGRA> : public BasePixelPtr 177 { 178 public: 179 void operator++() { mpPixel += 4; } 180 181 PIXBYTE GetRed() const { return mpPixel[2]; } 182 PIXBYTE GetGreen() const { return mpPixel[1]; } 183 PIXBYTE GetBlue() const { return mpPixel[0]; } 184 PIXBYTE GetAlpha() const { return mpPixel[3]; } 185 void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; } 186 187 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 188 { 189 mpPixel[0] = b; 190 mpPixel[1] = g; 191 mpPixel[2] = r; 192 } 193 }; 194 195 template <> 196 class TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_MSB_MASK> : public BasePixelPtr 197 { 198 public: 199 void operator++() { mpPixel += 2; } 200 201 // TODO: non565-RGB 202 PIXBYTE GetRed() const { return (mpPixel[0] & 0xF8U); } 203 PIXBYTE GetGreen() const { return (mpPixel[0]<<5U) | ((mpPixel[1]>>3U)&28U); } 204 PIXBYTE GetBlue() const { return (mpPixel[1]<<3U); } 205 PIXBYTE GetAlpha() const { return 0; } 206 void SetAlpha( PIXBYTE ) const {} 207 208 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 209 { 210 mpPixel[0] = ((g >> 5U) & 7U) | (r & 0xF8U); 211 mpPixel[1] = ((g & 28U)<< 3U) | (b >> 3U); 212 } 213 }; 214 215 template <> 216 class TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_LSB_MASK> : public BasePixelPtr 217 { 218 public: 219 void operator++() { mpPixel += 2; } 220 221 // TODO: non565-RGB 222 PIXBYTE GetRed() const { return (mpPixel[1] & 0xF8U); } 223 PIXBYTE GetGreen() const { return (mpPixel[1]<<5U) | ((mpPixel[0]>>3U)&28U); } 224 PIXBYTE GetBlue() const { return (mpPixel[0]<<3U); } 225 PIXBYTE GetAlpha() const { return 0; } 226 void SetAlpha( PIXBYTE ) const {} 227 228 void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const 229 { 230 mpPixel[0] = ((g & 28U)<< 3U) | (b >> 3U); 231 mpPixel[1] = ((g >> 5U) & 7U) | (r & 0xF8U); 232 } 233 }; 234 235 // ----------------------------------------------------------------------- 236 237 template <> 238 class TrueColorPixelPtr<BMP_FORMAT_8BIT_TC_MASK> : public BasePixelPtr 239 { 240 public: 241 void operator++() { mpPixel += 1; } 242 PIXBYTE GetAlpha() const { return mpPixel[0]; } 243 void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; } 244 void SetColor( PIXBYTE, PIXBYTE, PIXBYTE ) const {} 245 }; 246 247 // TODO: for some reason many Alpha maps are BMP_FORMAT_8BIT_PAL 248 // they should be BMP_FORMAT_8BIT_TC_MASK 249 template <> 250 class TrueColorPixelPtr<BMP_FORMAT_8BIT_PAL> 251 : public TrueColorPixelPtr<BMP_FORMAT_8BIT_TC_MASK> 252 {}; 253 254 #if 0 255 template <> 256 class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_MASK> : public BasePixelPtr 257 { 258 public: 259 void operator++() { mpPixel += 3; } 260 261 unsigned GetAlpha() const 262 { 263 unsigned nAlpha = mpPixel[0]; 264 nAlpha |= mpPixel[1] << 8U; 265 nAlpha |= mpPixel[2] << 16U; 266 return nAlpha; 267 } 268 269 void SetAlpha( unsigned nAlpha ) const 270 { 271 mpPixel[0] = nAlpha; 272 mpPixel[1] = nAlpha >> 8U; 273 mpPixel[2] = nAlpha >> 16U; 274 } 275 }; 276 277 template <> 278 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_MASK> : public BasePixelPtr 279 { 280 public: 281 void operator++() { mpPixel += 4; } 282 283 unsigned GetAlpha() const 284 { 285 #ifdef OSL_BIGENDIAN 286 unsigned nAlpha = *reinterpret_cast<unsigned*>( mpPixel ); 287 #else 288 unsigned nAlpha = mpPixel[0]; 289 nAlpha |= mpPixel[1] << 8U; 290 nAlpha |= mpPixel[2] << 16U; 291 nAlpha |= mpPixel[3] << 24U; 292 #endif 293 return nAlpha; 294 } 295 296 void SetAlpha( unsigned nAlpha ) const 297 { 298 #ifdef OSL_BIGENDIAN 299 *reinterpret_cast<unsigned*>( mpPixel ) = nAlpha; 300 #else 301 mpPixel[0] = nAlpha; 302 mpPixel[1] = nAlpha >> 8U; 303 mpPixel[2] = nAlpha >> 16U; 304 mpPixel[3] = nAlpha >> 24U; 305 #endif 306 } 307 }; 308 309 #endif 310 311 // ======================================================================= 312 // converting truecolor formats 313 314 template <sal_uLong SRCFMT, sal_uLong DSTFMT> 315 inline void ImplConvertPixel( const TrueColorPixelPtr<DSTFMT>& rDst, 316 const TrueColorPixelPtr<SRCFMT>& rSrc ) 317 { 318 rDst.SetColor( rSrc.GetRed(), rSrc.GetGreen(), rSrc.GetBlue() ); 319 rDst.SetAlpha( rSrc.GetAlpha() ); 320 } 321 322 // ----------------------------------------------------------------------- 323 324 template <> 325 inline void ImplConvertPixel<BMP_FORMAT_16BIT_TC_LSB_MASK, BMP_FORMAT_16BIT_TC_MSB_MASK> ( 326 const TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_MSB_MASK>& rDst, 327 const TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_LSB_MASK>& rSrc ) 328 { 329 // byte swapping 330 const PIXBYTE* pSrc = rSrc.GetRawPtr(); 331 PIXBYTE* pDst = rDst.GetRawPtr(); 332 pDst[1] = pSrc[0]; 333 pDst[0] = pSrc[1]; 334 } 335 336 // ----------------------------------------------------------------------- 337 338 template <sal_uLong SRCFMT, sal_uLong DSTFMT> 339 inline void ImplConvertLine( const TrueColorPixelPtr<DSTFMT>& rDst, 340 const TrueColorPixelPtr<SRCFMT>& rSrc, int nPixelCount ) 341 { 342 TrueColorPixelPtr<DSTFMT> aDst( rDst ); 343 TrueColorPixelPtr<SRCFMT> aSrc( rSrc ); 344 while( --nPixelCount >= 0 ) 345 { 346 ImplConvertPixel( aDst, aSrc ); 347 ++aSrc; 348 ++aDst; 349 } 350 } 351 352 // ======================================================================= 353 // alpha blending truecolor pixels 354 355 template <unsigned ALPHABITS, sal_uLong SRCFMT, sal_uLong DSTFMT> 356 inline void ImplBlendPixels( const TrueColorPixelPtr<DSTFMT>& rDst, 357 const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal ) 358 { 359 if( !nAlphaVal ) 360 ImplConvertPixel( rDst, rSrc ); 361 else if( nAlphaVal != ~(~0 << ALPHABITS) ) 362 { 363 static const unsigned nAlphaShift = (ALPHABITS > 8) ? 8 : ALPHABITS; 364 if( ALPHABITS > nAlphaShift ) 365 nAlphaVal >>= ALPHABITS - nAlphaShift; 366 367 int nR = rDst.GetRed(); 368 int nS = rSrc.GetRed(); 369 nR = nS + (((nR - nS) * nAlphaVal) >> nAlphaShift); 370 371 int nG = rDst.GetGreen(); 372 nS = rSrc.GetGreen(); 373 nG = nS + (((nG - nS) * nAlphaVal) >> nAlphaShift); 374 375 int nB = rDst.GetBlue(); 376 nS = rSrc.GetBlue(); 377 nB = nS + (((nB - nS) * nAlphaVal) >> nAlphaShift); 378 379 rDst.SetColor( sal::static_int_cast<PIXBYTE>(nR), 380 sal::static_int_cast<PIXBYTE>(nG), 381 sal::static_int_cast<PIXBYTE>(nB) ); 382 } 383 } 384 385 // ----------------------------------------------------------------------- 386 387 template <unsigned ALPHABITS, sal_uLong MASKFMT, sal_uLong SRCFMT, sal_uLong DSTFMT> 388 inline void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst, 389 const TrueColorPixelPtr<SRCFMT>& rSrc, const TrueColorPixelPtr<MASKFMT>& rMsk, 390 int nPixelCount ) 391 { 392 TrueColorPixelPtr<MASKFMT> aMsk( rMsk ); 393 TrueColorPixelPtr<DSTFMT> aDst( rDst ); 394 TrueColorPixelPtr<SRCFMT> aSrc( rSrc ); 395 while( --nPixelCount >= 0 ) 396 { 397 ImplBlendPixels<ALPHABITS>( aDst, aSrc, aMsk.GetAlpha() ); 398 ++aDst; 399 ++aSrc; 400 ++aMsk; 401 } 402 } 403 404 // ----------------------------------------------------------------------- 405 406 template <unsigned ALPHABITS, sal_uLong SRCFMT, sal_uLong DSTFMT> 407 inline void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst, 408 const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal, 409 int nPixelCount ) 410 { 411 if( nAlphaVal == ~(~0 << ALPHABITS) ) 412 ImplConvertLine( rDst, rSrc, nPixelCount ); 413 else if( nAlphaVal ) 414 { 415 TrueColorPixelPtr<SRCFMT> aSrc( rSrc ); 416 TrueColorPixelPtr<DSTFMT> aDst( rDst ); 417 while( --nPixelCount >= 0 ) 418 { 419 ImplBlendPixels<ALPHABITS>( aDst, aSrc, nAlphaVal ); 420 ++aDst; 421 ++aSrc; 422 } 423 } 424 } 425 426 // ======================================================================= 427 428 static bool ImplCopyImage( BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer ) 429 { 430 const int nSrcLinestep = rSrcBuffer.mnScanlineSize; 431 int nDstLinestep = rDstBuffer.mnScanlineSize; 432 433 const PIXBYTE* pRawSrc = rSrcBuffer.mpBits; 434 PIXBYTE* pRawDst = rDstBuffer.mpBits; 435 436 // source and destination don't match upside down 437 if( BMP_FORMAT_TOP_DOWN & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) ) 438 { 439 pRawDst += (rSrcBuffer.mnHeight - 1) * nDstLinestep; 440 nDstLinestep = -rDstBuffer.mnScanlineSize; 441 } 442 else if( nSrcLinestep == nDstLinestep ) 443 { 444 memcpy( pRawDst, pRawSrc, rSrcBuffer.mnHeight * nDstLinestep ); 445 return true; 446 } 447 448 int nByteWidth = nSrcLinestep; 449 if( nByteWidth > rDstBuffer.mnScanlineSize ) 450 nByteWidth = rDstBuffer.mnScanlineSize; 451 452 for( int y = rSrcBuffer.mnHeight; --y >= 0; ) 453 { 454 memcpy( pRawDst, pRawSrc, nByteWidth ); 455 pRawSrc += nSrcLinestep; 456 pRawDst += nDstLinestep; 457 } 458 459 return true; 460 } 461 462 // ----------------------------------------------------------------------- 463 464 template <sal_uLong DSTFMT,sal_uLong SRCFMT> 465 bool ImplConvertToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine, 466 BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer ) 467 { 468 // help the compiler to avoid instantiations of unneeded conversions 469 DBG_ASSERT( SRCFMT != DSTFMT, "ImplConvertToBitmap into same format"); 470 if( SRCFMT == DSTFMT ) 471 return false; 472 473 const int nSrcLinestep = rSrcBuffer.mnScanlineSize; 474 int nDstLinestep = rDstBuffer.mnScanlineSize; 475 476 TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits ); 477 478 // source and destination don't match upside down 479 if( BMP_FORMAT_TOP_DOWN & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) ) 480 { 481 aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep ); 482 nDstLinestep = -nDstLinestep; 483 } 484 485 for( int y = rSrcBuffer.mnHeight; --y >= 0; ) 486 { 487 ImplConvertLine( aDstLine, rSrcLine, rSrcBuffer.mnWidth ); 488 rSrcLine.AddByteOffset( nSrcLinestep ); 489 aDstLine.AddByteOffset( nDstLinestep ); 490 } 491 492 return true; 493 } 494 495 // ----------------------------------------------------------------------- 496 497 template <sal_uLong SRCFMT> 498 inline bool ImplConvertFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc ) 499 { 500 TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits ); 501 502 // select the matching instantiation for the destination's bitmap format 503 switch( rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN ) 504 { 505 case BMP_FORMAT_1BIT_MSB_PAL: 506 case BMP_FORMAT_1BIT_LSB_PAL: 507 case BMP_FORMAT_4BIT_MSN_PAL: 508 case BMP_FORMAT_4BIT_LSN_PAL: 509 case BMP_FORMAT_8BIT_PAL: 510 break; 511 512 case BMP_FORMAT_8BIT_TC_MASK: 513 // return ImplConvertToBitmap<BMP_FORMAT_8BIT_TC_MASK>( aSrcType, rDst, rSrc ); 514 case BMP_FORMAT_24BIT_TC_MASK: 515 // return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_MASK>( aSrcType, rDst, rSrc ); 516 case BMP_FORMAT_32BIT_TC_MASK: 517 // return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_MASK>( aSrcType, rDst, rSrc ); 518 break; 519 520 case BMP_FORMAT_16BIT_TC_MSB_MASK: 521 return ImplConvertToBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( aSrcType, rDst, rSrc ); 522 case BMP_FORMAT_16BIT_TC_LSB_MASK: 523 return ImplConvertToBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( aSrcType, rDst, rSrc ); 524 525 case BMP_FORMAT_24BIT_TC_BGR: 526 return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_BGR>( aSrcType, rDst, rSrc ); 527 case BMP_FORMAT_24BIT_TC_RGB: 528 return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDst, rSrc ); 529 530 case BMP_FORMAT_32BIT_TC_ABGR: 531 return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_ABGR>( aSrcType, rDst, rSrc ); 532 #ifdef FAST_ARGB_BGRA 533 case BMP_FORMAT_32BIT_TC_ARGB: 534 return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDst, rSrc ); 535 case BMP_FORMAT_32BIT_TC_BGRA: 536 return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_BGRA>( aSrcType, rDst, rSrc ); 537 #endif 538 case BMP_FORMAT_32BIT_TC_RGBA: 539 return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDst, rSrc ); 540 } 541 542 #ifdef DEBUG 543 static int nNotAccelerated = 0; 544 if( rSrc.mnWidth * rSrc.mnHeight >= 4000 ) 545 if( ++nNotAccelerated == 100 ) 546 { 547 int foo = 0; (void)foo; // so no warning is created when building on pro with debug 548 DBG_WARNING2( "ImplConvertFromBitmap for not accelerated case (0x%04X->0x%04X)", 549 rSrc.mnFormat, rDst.mnFormat ); 550 } 551 #endif 552 553 return false; 554 } 555 556 // ======================================================================= 557 558 // an universal stretching conversion is overkill in most common situations 559 // => performance benefits for speeding up the non-stretching cases 560 bool ImplFastBitmapConversion( BitmapBuffer& rDst, const BitmapBuffer& rSrc, 561 const SalTwoRect& rTR ) 562 { 563 if( bDisableFastBitops ) 564 return false; 565 566 // horizontal mirroring not implemented yet 567 if( rTR.mnDestWidth < 0 ) 568 return false; 569 // vertical mirroring 570 if( rTR.mnDestHeight < 0 ) 571 // TODO: rDst.mnFormat ^= BMP_FORMAT_TOP_DOWN; 572 return false; 573 574 // offseted conversion is not implemented yet 575 if( rTR.mnSrcX || rTR.mnSrcY ) 576 return false; 577 if( rTR.mnDestX || rTR.mnDestY ) 578 return false; 579 580 // stretched conversion is not implemented yet 581 if( rTR.mnDestWidth != rTR.mnSrcWidth ) 582 return false; 583 if( rTR.mnDestHeight!= rTR.mnSrcHeight ) 584 return false; 585 586 // check source image size 587 if( rSrc.mnWidth < rTR.mnSrcX + rTR.mnSrcWidth ) 588 return false; 589 if( rSrc.mnHeight < rTR.mnSrcY + rTR.mnSrcHeight ) 590 return false; 591 592 // check dest image size 593 if( rDst.mnWidth < rTR.mnDestX + rTR.mnDestWidth ) 594 return false; 595 if( rDst.mnHeight < rTR.mnDestY + rTR.mnDestHeight ) 596 return false; 597 598 const sal_uLong nSrcFormat = rSrc.mnFormat & ~BMP_FORMAT_TOP_DOWN; 599 const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN; 600 601 // TODO: also implement conversions for 16bit colormasks with non-565 format 602 if( nSrcFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) ) 603 if( rSrc.maColorMask.GetRedMask() != 0xF800 604 || rSrc.maColorMask.GetGreenMask()!= 0x07E0 605 || rSrc.maColorMask.GetBlueMask() != 0x001F ) 606 return false; 607 if( nDstFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) ) 608 if( rDst.maColorMask.GetRedMask() != 0xF800 609 || rDst.maColorMask.GetGreenMask()!= 0x07E0 610 || rDst.maColorMask.GetBlueMask() != 0x001F ) 611 return false; 612 613 // special handling of trivial cases 614 if( nSrcFormat == nDstFormat ) 615 { 616 // accelerated palette conversions not yet implemented 617 if( rSrc.maPalette != rDst.maPalette ) 618 return false; 619 return ImplCopyImage( rDst, rSrc ); 620 } 621 622 // select the matching instantiation for the source's bitmap format 623 switch( nSrcFormat ) 624 { 625 case BMP_FORMAT_1BIT_MSB_PAL: 626 case BMP_FORMAT_1BIT_LSB_PAL: 627 case BMP_FORMAT_4BIT_MSN_PAL: 628 case BMP_FORMAT_4BIT_LSN_PAL: 629 case BMP_FORMAT_8BIT_PAL: 630 break; 631 632 case BMP_FORMAT_8BIT_TC_MASK: 633 // return ImplConvertFromBitmap<BMP_FORMAT_8BIT_TC_MASK>( rDst, rSrc ); 634 case BMP_FORMAT_24BIT_TC_MASK: 635 // return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_MASK>( rDst, rSrc ); 636 case BMP_FORMAT_32BIT_TC_MASK: 637 // return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_MASK>( rDst, rSrc ); 638 break; 639 640 case BMP_FORMAT_16BIT_TC_MSB_MASK: 641 return ImplConvertFromBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( rDst, rSrc ); 642 case BMP_FORMAT_16BIT_TC_LSB_MASK: 643 return ImplConvertFromBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( rDst, rSrc ); 644 645 case BMP_FORMAT_24BIT_TC_BGR: 646 return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_BGR>( rDst, rSrc ); 647 case BMP_FORMAT_24BIT_TC_RGB: 648 return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_RGB>( rDst, rSrc ); 649 650 case BMP_FORMAT_32BIT_TC_ABGR: 651 return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_ABGR>( rDst, rSrc ); 652 #ifdef FAST_ARGB_BGRA 653 case BMP_FORMAT_32BIT_TC_ARGB: 654 return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_ARGB>( rDst, rSrc ); 655 case BMP_FORMAT_32BIT_TC_BGRA: 656 return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_BGRA>( rDst, rSrc ); 657 #endif 658 case BMP_FORMAT_32BIT_TC_RGBA: 659 return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_RGBA>( rDst, rSrc ); 660 } 661 662 #ifdef DEBUG 663 static int nNotAccelerated = 0; 664 if( rSrc.mnWidth * rSrc.mnHeight >= 4000 ) 665 { 666 if( ++nNotAccelerated == 100 ) 667 { 668 int foo = 0; (void)foo; // so no warning is created when building on pro with debug 669 DBG_WARNING2( "ImplFastBitmapConversion for not accelerated case (0x%04X->0x%04X)", rSrc.mnFormat, rDst.mnFormat ); 670 } 671 } 672 #endif 673 674 return false; 675 } 676 677 // ======================================================================= 678 679 template <sal_uLong DSTFMT,sal_uLong SRCFMT> //,sal_uLong MSKFMT> 680 bool ImplBlendToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine, 681 BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer, 682 const BitmapBuffer& rMskBuffer ) 683 { 684 //DBG_ASSERT( rMskBuffer.mnFormat == MSKFMT, "FastBmp BlendImage: wrong MSKFMT" ); 685 DBG_ASSERT( rMskBuffer.mnFormat == BMP_FORMAT_8BIT_PAL, "FastBmp BlendImage: unusual MSKFMT" ); 686 687 const int nSrcLinestep = rSrcBuffer.mnScanlineSize; 688 int nMskLinestep = rMskBuffer.mnScanlineSize; 689 int nDstLinestep = rDstBuffer.mnScanlineSize; 690 691 TrueColorPixelPtr<BMP_FORMAT_8BIT_PAL> aMskLine; aMskLine.SetRawPtr( rMskBuffer.mpBits ); 692 TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits ); 693 694 // special case for single line masks 695 if( rMskBuffer.mnHeight == 1 ) 696 nMskLinestep = 0; 697 698 // source and mask don't match: upside down 699 if( (rSrcBuffer.mnFormat ^ rMskBuffer.mnFormat) & BMP_FORMAT_TOP_DOWN ) 700 { 701 aMskLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nMskLinestep ); 702 nMskLinestep = -nMskLinestep; 703 } 704 705 // source and destination don't match: upside down 706 if( (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) & BMP_FORMAT_TOP_DOWN ) 707 { 708 aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep ); 709 nDstLinestep = -nDstLinestep; 710 } 711 712 for( int y = rSrcBuffer.mnHeight; --y >= 0; ) 713 { 714 ImplBlendLines<8>( aDstLine, rSrcLine, aMskLine, rDstBuffer.mnWidth ); 715 aDstLine.AddByteOffset( nDstLinestep ); 716 rSrcLine.AddByteOffset( nSrcLinestep ); 717 aMskLine.AddByteOffset( nMskLinestep ); 718 } 719 720 return true; 721 } 722 723 // some specializations to reduce the code size 724 template <> 725 inline bool ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_BGR,BMP_FORMAT_24BIT_TC_BGR>( 726 TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_BGR>&, 727 BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer, 728 const BitmapBuffer& rMskBuffer ) 729 { 730 TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_RGB> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits ); 731 return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer ); 732 } 733 734 template <> 735 inline bool ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ABGR,BMP_FORMAT_32BIT_TC_ABGR>( 736 TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ABGR>&, 737 BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer, 738 const BitmapBuffer& rMskBuffer ) 739 { 740 TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ARGB> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits ); 741 return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer ); 742 } 743 744 template <> 745 inline bool ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_BGRA,BMP_FORMAT_32BIT_TC_BGRA>( 746 TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_BGRA>&, 747 BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer, 748 const BitmapBuffer& rMskBuffer ) 749 { 750 TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_RGBA> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits ); 751 return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer ); 752 } 753 754 // ----------------------------------------------------------------------- 755 756 template <sal_uLong SRCFMT> 757 bool ImplBlendFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc, const BitmapBuffer& rMsk ) 758 { 759 TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits ); 760 761 // select the matching instantiation for the destination's bitmap format 762 switch( rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN ) 763 { 764 case BMP_FORMAT_1BIT_MSB_PAL: 765 case BMP_FORMAT_1BIT_LSB_PAL: 766 case BMP_FORMAT_4BIT_MSN_PAL: 767 case BMP_FORMAT_4BIT_LSN_PAL: 768 case BMP_FORMAT_8BIT_PAL: 769 break; 770 771 case BMP_FORMAT_8BIT_TC_MASK: 772 // return ImplBlendToBitmap<BMP_FORMAT_8BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk ); 773 case BMP_FORMAT_24BIT_TC_MASK: 774 // return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk ); 775 case BMP_FORMAT_32BIT_TC_MASK: 776 // return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk ); 777 break; 778 779 case BMP_FORMAT_16BIT_TC_MSB_MASK: 780 return ImplBlendToBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( aSrcType, rDst, rSrc, rMsk ); 781 case BMP_FORMAT_16BIT_TC_LSB_MASK: 782 return ImplBlendToBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( aSrcType, rDst, rSrc, rMsk ); 783 784 case BMP_FORMAT_24BIT_TC_BGR: 785 return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_BGR>( aSrcType, rDst, rSrc, rMsk ); 786 case BMP_FORMAT_24BIT_TC_RGB: 787 return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDst, rSrc, rMsk ); 788 789 case BMP_FORMAT_32BIT_TC_ABGR: 790 return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ABGR>( aSrcType, rDst, rSrc, rMsk ); 791 #ifdef FAST_ARGB_BGRA 792 case BMP_FORMAT_32BIT_TC_ARGB: 793 return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDst, rSrc, rMsk ); 794 case BMP_FORMAT_32BIT_TC_BGRA: 795 return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_BGRA>( aSrcType, rDst, rSrc, rMsk ); 796 #endif 797 case BMP_FORMAT_32BIT_TC_RGBA: 798 return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDst, rSrc, rMsk ); 799 } 800 801 #ifdef DEBUG 802 static int nNotAccelerated = 0; 803 if( rSrc.mnWidth * rSrc.mnHeight >= 4000 ) 804 if( ++nNotAccelerated == 100 ) 805 { 806 int foo = 0; (void)foo; // so no warning is created when building on pro with debug 807 DBG_WARNING3( "ImplBlendFromBitmap for not accelerated case (0x%04X*0x%04X->0x%04X)", 808 rSrc.mnFormat, rMsk.mnFormat, rDst.mnFormat ); 809 } 810 #endif 811 812 return false; 813 } 814 815 // ----------------------------------------------------------------------- 816 817 bool ImplFastBitmapBlending( BitmapWriteAccess& rDstWA, 818 const BitmapReadAccess& rSrcRA, const BitmapReadAccess& rMskRA, 819 const SalTwoRect& rTR ) 820 { 821 if( bDisableFastBitops ) 822 return false; 823 824 // accelerated blending of paletted bitmaps not implemented yet 825 if( rSrcRA.HasPalette() ) 826 return false; 827 if( rDstWA.HasPalette() ) 828 return false; 829 // TODO: either get rid of mask's use of 8BIT_PAL or check the palette 830 831 // horizontal mirroring not implemented yet 832 if( rTR.mnDestWidth < 0 ) 833 return false; 834 // vertical mirroring 835 if( rTR.mnDestHeight < 0 ) 836 // TODO: rDst.mnFormat ^= BMP_FORMAT_TOP_DOWN; 837 return false; 838 839 // offseted blending is not implemented yet 840 if( rTR.mnSrcX || rTR.mnSrcY ) 841 return false; 842 if( rTR.mnDestX || rTR.mnDestY ) 843 return false; 844 845 // stretched blending is not implemented yet 846 if( rTR.mnDestWidth != rTR.mnSrcWidth ) 847 return false; 848 if( rTR.mnDestHeight!= rTR.mnSrcHeight ) 849 return false; 850 851 // check source image size 852 if( rSrcRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth ) 853 return false; 854 if( rSrcRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight ) 855 return false; 856 857 // check mask image size 858 if( rMskRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth ) 859 return false; 860 if( rMskRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight ) 861 if( rMskRA.Height() != 1 ) 862 return false; 863 864 // check dest image size 865 if( rDstWA.Width() < rTR.mnDestX + rTR.mnDestWidth ) 866 return false; 867 if( rDstWA.Height() < rTR.mnDestY + rTR.mnDestHeight ) 868 return false; 869 870 BitmapBuffer& rDst = *rDstWA.ImplGetBitmapBuffer(); 871 const BitmapBuffer& rSrc = *rSrcRA.ImplGetBitmapBuffer(); 872 const BitmapBuffer& rMsk = *rMskRA.ImplGetBitmapBuffer(); 873 874 const sal_uLong nSrcFormat = rSrc.mnFormat & ~BMP_FORMAT_TOP_DOWN; 875 const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN; 876 877 // accelerated conversions for 16bit colormasks with non-565 format are not yet implemented 878 if( nSrcFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) ) 879 if( rSrc.maColorMask.GetRedMask() != 0xF800 880 || rSrc.maColorMask.GetGreenMask()!= 0x07E0 881 || rSrc.maColorMask.GetBlueMask() != 0x001F) 882 return false; 883 if( nDstFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) ) 884 if( rDst.maColorMask.GetRedMask() != 0xF800 885 || rDst.maColorMask.GetGreenMask()!= 0x07E0 886 || rDst.maColorMask.GetBlueMask() != 0x001F) 887 return false; 888 889 // select the matching instantiation for the source's bitmap format 890 switch( nSrcFormat ) 891 { 892 case BMP_FORMAT_1BIT_MSB_PAL: 893 case BMP_FORMAT_1BIT_LSB_PAL: 894 case BMP_FORMAT_4BIT_MSN_PAL: 895 case BMP_FORMAT_4BIT_LSN_PAL: 896 case BMP_FORMAT_8BIT_PAL: 897 break; 898 899 case BMP_FORMAT_8BIT_TC_MASK: 900 // return ImplBlendFromBitmap<BMP_FORMAT_8BIT_TC_MASK>( rDst, rSrc ); 901 case BMP_FORMAT_24BIT_TC_MASK: 902 // return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_MASK>( rDst, rSrc ); 903 case BMP_FORMAT_32BIT_TC_MASK: 904 // return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_MASK>( rDst, rSrc ); 905 break; 906 907 case BMP_FORMAT_16BIT_TC_MSB_MASK: 908 return ImplBlendFromBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( rDst, rSrc, rMsk ); 909 case BMP_FORMAT_16BIT_TC_LSB_MASK: 910 return ImplBlendFromBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( rDst, rSrc, rMsk ); 911 912 case BMP_FORMAT_24BIT_TC_BGR: 913 return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_BGR>( rDst, rSrc, rMsk ); 914 case BMP_FORMAT_24BIT_TC_RGB: 915 return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_RGB>( rDst, rSrc, rMsk ); 916 917 case BMP_FORMAT_32BIT_TC_ABGR: 918 return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_ABGR>( rDst, rSrc, rMsk ); 919 #ifdef FAST_ARGB_BGRA 920 case BMP_FORMAT_32BIT_TC_ARGB: 921 return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_ARGB>( rDst, rSrc, rMsk ); 922 case BMP_FORMAT_32BIT_TC_BGRA: 923 return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_BGRA>( rDst, rSrc, rMsk ); 924 #endif 925 case BMP_FORMAT_32BIT_TC_RGBA: 926 return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_RGBA>( rDst, rSrc, rMsk ); 927 } 928 929 #ifdef DEBUG 930 static int nNotAccelerated = 0; 931 if( rSrc.mnWidth * rSrc.mnHeight >= 4000 ) 932 if( ++nNotAccelerated == 100 ) 933 { 934 int foo = 0; (void)foo; // so no warning is created when building on pro with debug 935 DBG_WARNING3( "ImplFastBlend for not accelerated case (0x%04X*0x%04X->0x%04X)", 936 rSrc.mnFormat, rMsk.mnFormat, rDst.mnFormat ); 937 } 938 #endif 939 940 return false; 941 } 942 943 bool ImplFastEraseBitmap( BitmapBuffer& rDst, const BitmapColor& rColor ) 944 { 945 if( bDisableFastBitops ) 946 return false; 947 948 const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN; 949 950 // erasing a bitmap is often just a byte-wise memory fill 951 bool bByteFill = true; 952 sal_uInt8 nFillByte; 953 954 switch( nDstFormat ) 955 { 956 case BMP_FORMAT_1BIT_MSB_PAL: 957 case BMP_FORMAT_1BIT_LSB_PAL: 958 nFillByte = rColor.GetIndex(); 959 nFillByte = static_cast<sal_uInt8>( -(nFillByte & 1) ); // 0x00 or 0xFF 960 break; 961 case BMP_FORMAT_4BIT_MSN_PAL: 962 case BMP_FORMAT_4BIT_LSN_PAL: 963 nFillByte = rColor.GetIndex(); 964 nFillByte &= 0x0F; 965 nFillByte |= (nFillByte << 4); 966 break; 967 case BMP_FORMAT_8BIT_PAL: 968 case BMP_FORMAT_8BIT_TC_MASK: 969 nFillByte = rColor.GetIndex(); 970 break; 971 972 case BMP_FORMAT_24BIT_TC_MASK: 973 case BMP_FORMAT_24BIT_TC_BGR: 974 case BMP_FORMAT_24BIT_TC_RGB: 975 nFillByte = rColor.GetRed(); 976 if( (nFillByte != rColor.GetGreen()) 977 || (nFillByte != rColor.GetBlue()) ) 978 bByteFill = false; 979 break; 980 981 default: 982 bByteFill = false; 983 nFillByte = 0x00; 984 break; 985 } 986 987 if( bByteFill ) 988 { 989 long nByteCount = rDst.mnHeight * rDst.mnScanlineSize; 990 rtl_fillMemory( rDst.mpBits, nByteCount, nFillByte ); 991 return true; 992 } 993 994 // TODO: handle other bitmap formats 995 switch( nDstFormat ) 996 { 997 case BMP_FORMAT_32BIT_TC_MASK: 998 case BMP_FORMAT_16BIT_TC_MSB_MASK: 999 case BMP_FORMAT_16BIT_TC_LSB_MASK: 1000 1001 case BMP_FORMAT_24BIT_TC_BGR: 1002 case BMP_FORMAT_24BIT_TC_RGB: 1003 1004 case BMP_FORMAT_32BIT_TC_ABGR: 1005 #ifdef FAST_ARGB_BGRA 1006 case BMP_FORMAT_32BIT_TC_ARGB: 1007 case BMP_FORMAT_32BIT_TC_BGRA: 1008 #endif 1009 case BMP_FORMAT_32BIT_TC_RGBA: 1010 break; 1011 1012 default: 1013 break; 1014 } 1015 1016 return false; 1017 } 1018 1019 // ======================================================================= 1020 1021 #else // NO_OPTIMIZED_BITMAP_ACCESS 1022 1023 bool ImplFastBitmapConversion( BitmapBuffer&, const BitmapBuffer& ) 1024 { 1025 return false; 1026 } 1027 1028 bool ImplFastBitmapBlending( BitmapWriteAccess&, 1029 const BitmapReadAccess&, const BitmapReadAccess&, 1030 const Size&, const Point& ) 1031 { 1032 return false; 1033 } 1034 1035 bool ImplFastEraseBitmap( BitmapBuffer&, const BitmapColor& ) 1036 { 1037 return false; 1038 } 1039 1040 #endif 1041