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 #ifndef _SV_BMPACC_HXX 25 #define _SV_BMPACC_HXX 26 27 #include <vcl/sv.h> 28 #include <vcl/dllapi.h> 29 #include <vcl/salbtype.hxx> 30 #include <vcl/bitmap.hxx> 31 32 //#if 0 // _SOLAR__PRIVATE 33 34 // -------------------- 35 // - Access defines - 36 // -------------------- 37 38 #define DECL_FORMAT_GETPIXEL( Format ) \ 39 static BitmapColor GetPixelFor##Format( ConstScanline pScanline, long nX, const ColorMask& rMask ); 40 41 #define DECL_FORMAT_SETPIXEL( Format ) \ 42 static void SetPixelFor##Format( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask ); 43 44 #define DECL_FORMAT( Format ) \ 45 DECL_FORMAT_GETPIXEL( Format ) \ 46 DECL_FORMAT_SETPIXEL( Format ) 47 48 #define IMPL_FORMAT_GETPIXEL( Format ) \ 49 BitmapColor BitmapReadAccess::GetPixelFor##Format( ConstScanline pScanline, long nX, const ColorMask& rMask ) 50 51 #define IMPL_FORMAT_GETPIXEL_NOMASK( Format ) \ 52 BitmapColor BitmapReadAccess::GetPixelFor##Format( ConstScanline pScanline, long nX, const ColorMask& ) 53 54 #define IMPL_FORMAT_SETPIXEL( Format ) \ 55 void BitmapReadAccess::SetPixelFor##Format( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask ) 56 57 #define IMPL_FORMAT_SETPIXEL_NOMASK( Format ) \ 58 void BitmapReadAccess::SetPixelFor##Format( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& ) 59 60 #define CASE_FORMAT( Format ) \ 61 case( BMP_FORMAT##Format ): \ 62 { \ 63 mFncGetPixel = GetPixelFor##Format;\ 64 mFncSetPixel = SetPixelFor##Format;\ 65 } \ 66 break; 67 68 //#endif // __PRIVATE 69 70 // -------------------- 71 // - Access functions - 72 // -------------------- 73 74 typedef BitmapColor (*FncGetPixel)( ConstScanline pScanline, long nX, const ColorMask& rMask ); 75 typedef void (*FncSetPixel)( Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask& rMask ); 76 77 // -------------------- 78 // - BitmapReadAccess - 79 // -------------------- 80 81 class VCL_DLLPUBLIC BitmapReadAccess 82 { 83 friend class BitmapWriteAccess; 84 85 private: 86 87 BitmapReadAccess() {} 88 BitmapReadAccess( const BitmapReadAccess& ) {} 89 BitmapReadAccess& operator=( const BitmapReadAccess& ) { return *this; } 90 91 protected: 92 Bitmap maBitmap; 93 BitmapBuffer* mpBuffer; 94 Scanline* mpScanBuf; 95 ColorMask maColorMask; 96 FncGetPixel mFncGetPixel; 97 FncSetPixel mFncSetPixel; 98 sal_Bool mbModify; 99 100 //#if 0 // _SOLAR__PRIVATE 101 102 SAL_DLLPRIVATE void ImplCreate( Bitmap& rBitmap ); 103 SAL_DLLPRIVATE void ImplDestroy(); 104 SAL_DLLPRIVATE sal_Bool ImplSetAccessPointers( sal_uLong nFormat ); 105 106 public: 107 108 SAL_DLLPRIVATE void ImplZeroInitUnusedBits(); 109 SAL_DLLPRIVATE BitmapBuffer* ImplGetBitmapBuffer() const { return mpBuffer; } 110 111 DECL_FORMAT( _1BIT_MSB_PAL ) 112 DECL_FORMAT( _1BIT_LSB_PAL ) 113 DECL_FORMAT( _4BIT_MSN_PAL ) 114 DECL_FORMAT( _4BIT_LSN_PAL ) 115 DECL_FORMAT( _8BIT_PAL ) 116 DECL_FORMAT( _8BIT_TC_MASK ) 117 DECL_FORMAT( _16BIT_TC_MSB_MASK ) 118 DECL_FORMAT( _16BIT_TC_LSB_MASK ) 119 DECL_FORMAT( _24BIT_TC_BGR ) 120 DECL_FORMAT( _24BIT_TC_RGB ) 121 DECL_FORMAT( _24BIT_TC_MASK ) 122 DECL_FORMAT( _32BIT_TC_ABGR ) 123 DECL_FORMAT( _32BIT_TC_ARGB ) 124 DECL_FORMAT( _32BIT_TC_BGRA ) 125 DECL_FORMAT( _32BIT_TC_RGBA ) 126 DECL_FORMAT( _32BIT_TC_MASK ) 127 //#endif // __PRIVATE 128 129 protected: 130 BitmapReadAccess( Bitmap& rBitmap, sal_Bool bModify ); 131 132 void Flush(); 133 void ReAccess( sal_Bool bModify ); 134 135 public: 136 BitmapReadAccess( Bitmap& rBitmap ); 137 virtual ~BitmapReadAccess(); 138 139 inline sal_Bool operator!() const; 140 141 inline long Width() const; 142 inline long Height() const; 143 inline Point TopLeft() const; 144 inline Point BottomRight() const; 145 146 inline sal_Bool IsTopDown() const; 147 inline sal_Bool IsBottomUp() const; 148 149 inline sal_uLong GetScanlineFormat() const; 150 inline sal_uLong GetScanlineSize() const; 151 152 inline sal_uInt16 GetBitCount() const; 153 inline BitmapColor GetBestMatchingColor( const BitmapColor& rBitmapColor ); 154 155 inline Scanline GetBuffer() const; 156 inline Scanline GetScanline( long nY ) const; 157 158 inline sal_Bool HasPalette() const; 159 inline const BitmapPalette& GetPalette() const; 160 inline sal_uInt16 GetPaletteEntryCount() const; 161 inline const BitmapColor& GetPaletteColor( sal_uInt16 nColor ) const; 162 inline const BitmapColor& GetBestPaletteColor( const BitmapColor& rBitmapColor ) const; 163 sal_uInt16 GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const; 164 165 inline sal_Bool HasColorMask() const; 166 inline ColorMask& GetColorMask() const; 167 168 inline BitmapColor GetPixelFromData( const sal_uInt8* pData, long nX ) const; 169 inline void SetPixelOnData( sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor ); 170 inline BitmapColor GetPixel( long nY, long nX ) const; 171 inline BitmapColor GetColor( long nY, long nX ) const; 172 inline sal_uInt8 GetPixelIndex( long nY, long nX ) const; 173 inline sal_uInt8 GetLuminance( long nY, long nX ) const; 174 }; 175 176 // --------------------- 177 // - BitmapWriteAccess - 178 // --------------------- 179 180 class VCL_DLLPUBLIC BitmapWriteAccess : public BitmapReadAccess 181 { 182 public: 183 184 BitmapWriteAccess( Bitmap& rBitmap ); 185 virtual ~BitmapWriteAccess(); 186 187 void CopyScanline( long nY, const BitmapReadAccess& rReadAcc ); 188 void CopyScanline( long nY, ConstScanline aSrcScanline, 189 sal_uLong nSrcScanlineFormat, sal_uLong nSrcScanlineSize ); 190 191 void CopyBuffer( const BitmapReadAccess& rReadAcc ); 192 193 inline void SetPalette( const BitmapPalette& rPalette ); 194 inline void SetPaletteEntryCount( sal_uInt16 nCount ); 195 inline void SetPaletteColor( sal_uInt16 nColor, const BitmapColor& rBitmapColor ); 196 197 inline void SetPixel( long nY, long nX, const BitmapColor& rBitmapColor ); 198 inline void SetPixelIndex( long nY, long nX, sal_uInt8 cIndex ); 199 200 void SetLineColor(); 201 void SetLineColor( const Color& rColor ); 202 Color GetLineColor() const; 203 204 void SetFillColor(); 205 void SetFillColor( const Color& rColor ); 206 Color GetFillColor() const; 207 208 void Erase( const Color& rColor ); 209 210 void DrawLine( const Point& rStart, const Point& rEnd ); 211 212 void FillRect( const Rectangle& rRect ); 213 void DrawRect( const Rectangle& rRect ); 214 215 void FillPolygon( const Polygon& rPoly ); 216 void DrawPolygon( const Polygon& rPoly ); 217 218 void FillPolyPolygon( const PolyPolygon& rPoly ); 219 void DrawPolyPolygon( const PolyPolygon& rPolyPoly ); 220 221 private: 222 223 BitmapColor* mpLineColor; 224 BitmapColor* mpFillColor; 225 226 BitmapWriteAccess() {} 227 BitmapWriteAccess( const BitmapWriteAccess& ) : BitmapReadAccess() {} 228 BitmapWriteAccess& operator=( const BitmapWriteAccess& ) { return *this; } 229 }; 230 231 // ------------------- 232 // - Accessor Helper - 233 // ------------------- 234 235 /** This template handles BitmapAccess the RAII way. 236 237 Please don't use directly, but the ready-made typedefs for 238 BitmapReadAccess and BitmapWriteAccess below. 239 */ 240 template < class Access > class ScopedBitmapAccess 241 { 242 public: 243 ScopedBitmapAccess( Access* pAccess, 244 Bitmap& rBitmap ) : 245 mpAccess( pAccess ), 246 mrBitmap( rBitmap ) 247 { 248 } 249 250 ~ScopedBitmapAccess() 251 { 252 mrBitmap.ReleaseAccess( mpAccess ); 253 } 254 255 Access* get() { return mpAccess; } 256 const Access* get() const { return mpAccess; } 257 258 Access* operator->() { return mpAccess; } 259 const Access* operator->() const { return mpAccess; } 260 261 Access& operator*() { return *mpAccess; } 262 const Access& operator*() const { return *mpAccess; } 263 264 private: 265 Access* mpAccess; 266 Bitmap& mrBitmap; 267 }; 268 269 /** This wrapper handles BitmapReadAccess the RAII way. 270 271 Use as follows: 272 Bitmap aBitmap 273 ScopedBitmapReadAccess pReadAccess( aBitmap.AcquireReadAccess(), aBitmap ); 274 pReadAccess->SetPixel()... 275 276 @attention for practical reasons, ScopedBitmapReadAccess stores a 277 reference to the provided bitmap, thus, make sure that the bitmap 278 specified at construction time lives at least as long as the 279 ScopedBitmapReadAccess. 280 */ 281 typedef ScopedBitmapAccess< BitmapReadAccess > ScopedBitmapReadAccess; 282 283 /** This wrapper handles BitmapWriteAccess the RAII way. 284 285 Use as follows: 286 Bitmap aBitmap 287 ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(), aBitmap ); 288 pWriteAccess->SetPixel()... 289 290 @attention for practical reasons, ScopedBitmapWriteAccess stores a 291 reference to the provided bitmap, thus, make sure that the bitmap 292 specified at construction time lives at least as long as the 293 ScopedBitmapWriteAccess. 294 */ 295 typedef ScopedBitmapAccess< BitmapWriteAccess > ScopedBitmapWriteAccess; 296 297 // ----------- 298 // - Inlines - 299 // ----------- 300 301 inline sal_Bool BitmapReadAccess::operator!() const 302 { 303 return( mpBuffer == NULL ); 304 } 305 306 // ------------------------------------------------------------------ 307 308 inline long BitmapReadAccess::Width() const 309 { 310 return( mpBuffer ? mpBuffer->mnWidth : 0L ); 311 } 312 313 // ------------------------------------------------------------------ 314 315 inline long BitmapReadAccess::Height() const 316 { 317 return( mpBuffer ? mpBuffer->mnHeight : 0L ); 318 } 319 320 // ------------------------------------------------------------------ 321 322 inline Point BitmapReadAccess::TopLeft() const 323 { 324 return Point(); 325 } 326 327 // ------------------------------------------------------------------ 328 329 inline Point BitmapReadAccess::BottomRight() const 330 { 331 return Point( Width() - 1L, Height() - 1L ); 332 } 333 334 // ------------------------------------------------------------------ 335 336 inline sal_Bool BitmapReadAccess::IsTopDown() const 337 { 338 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 339 return( mpBuffer ? sal::static_int_cast<sal_Bool>( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) : sal_False ); 340 } 341 342 // ------------------------------------------------------------------ 343 344 inline sal_Bool BitmapReadAccess::IsBottomUp() const 345 { 346 return !IsTopDown(); 347 } 348 349 // ------------------------------------------------------------------ 350 351 inline sal_uLong BitmapReadAccess::GetScanlineFormat() const 352 { 353 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 354 return( mpBuffer ? BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) : 0UL ); 355 } 356 357 // ------------------------------------------------------------------ 358 359 inline sal_uLong BitmapReadAccess::GetScanlineSize() const 360 { 361 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 362 return( mpBuffer ? mpBuffer->mnScanlineSize : 0UL ); 363 } 364 365 // ------------------------------------------------------------------ 366 367 inline sal_uInt16 BitmapReadAccess::GetBitCount() const 368 { 369 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 370 return( mpBuffer ? mpBuffer->mnBitCount : 0 ); 371 } 372 373 // ------------------------------------------------------------------ 374 375 inline BitmapColor BitmapReadAccess::GetBestMatchingColor( const BitmapColor& rBitmapColor ) 376 { 377 if( HasPalette() ) 378 return BitmapColor( (sal_uInt8) GetBestPaletteIndex( rBitmapColor ) ); 379 else 380 return rBitmapColor; 381 } 382 383 // ------------------------------------------------------------------ 384 385 inline Scanline BitmapReadAccess::GetBuffer() const 386 { 387 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 388 return( mpBuffer ? mpBuffer->mpBits : NULL ); 389 } 390 391 // ------------------------------------------------------------------ 392 393 inline Scanline BitmapReadAccess::GetScanline( long nY ) const 394 { 395 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 396 DBG_ASSERT( nY < mpBuffer->mnHeight, "y-coordinate out of range!" ); 397 return( mpBuffer ? mpScanBuf[ nY ] : NULL ); 398 } 399 400 // ------------------------------------------------------------------ 401 402 inline sal_Bool BitmapReadAccess::HasPalette() const 403 { 404 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 405 return( mpBuffer && !!mpBuffer->maPalette ); 406 } 407 408 // ------------------------------------------------------------------ 409 410 inline const BitmapPalette& BitmapReadAccess::GetPalette() const 411 { 412 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 413 return mpBuffer->maPalette; 414 } 415 416 // ------------------------------------------------------------------ 417 418 inline sal_uInt16 BitmapReadAccess::GetPaletteEntryCount() const 419 { 420 DBG_ASSERT( HasPalette(), "Bitmap has no palette!" ); 421 return( HasPalette() ? mpBuffer->maPalette.GetEntryCount() : 0 ); 422 } 423 424 // ------------------------------------------------------------------ 425 426 inline const BitmapColor& BitmapReadAccess::GetPaletteColor( sal_uInt16 nColor ) const 427 { 428 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 429 DBG_ASSERT( HasPalette(), "Bitmap has no palette!" ); 430 return mpBuffer->maPalette[ nColor ]; 431 } 432 433 // ------------------------------------------------------------------ 434 435 inline const BitmapColor& BitmapReadAccess::GetBestPaletteColor( const BitmapColor& rBitmapColor ) const 436 { 437 return GetPaletteColor( GetBestPaletteIndex( rBitmapColor ) ); 438 } 439 440 // ------------------------------------------------------------------ 441 442 inline sal_Bool BitmapReadAccess::HasColorMask() const 443 { 444 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 445 const sal_uLong nFormat = BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ); 446 447 return( nFormat == BMP_FORMAT_8BIT_TC_MASK || 448 nFormat == BMP_FORMAT_16BIT_TC_MSB_MASK || 449 nFormat == BMP_FORMAT_16BIT_TC_LSB_MASK || 450 nFormat == BMP_FORMAT_24BIT_TC_MASK || 451 nFormat == BMP_FORMAT_32BIT_TC_MASK ); 452 } 453 454 // ------------------------------------------------------------------ 455 456 inline ColorMask& BitmapReadAccess::GetColorMask() const 457 { 458 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 459 return mpBuffer->maColorMask; 460 } 461 462 // ------------------------------------------------------------------ 463 464 inline BitmapColor BitmapReadAccess::GetPixel( long nY, long nX ) const 465 { 466 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 467 DBG_ASSERT( nX < mpBuffer->mnWidth, "x-coordinate out of range!" ); 468 DBG_ASSERT( nY < mpBuffer->mnHeight, "y-coordinate out of range!" ); 469 return mFncGetPixel( mpScanBuf[ nY ], nX, maColorMask ); 470 } 471 472 inline sal_uInt8 BitmapReadAccess::GetPixelIndex( long nY, long nX ) const 473 { 474 return GetPixel( nY, nX ).GetBlueOrIndex(); 475 } 476 477 // ------------------------------------------------------------------ 478 479 inline BitmapColor BitmapReadAccess::GetPixelFromData( const sal_uInt8* pData, long nX ) const 480 { 481 DBG_ASSERT( pData, "Access is not valid!" ); 482 return mFncGetPixel( pData, nX, maColorMask ); 483 } 484 485 // ------------------------------------------------------------------ 486 487 inline void BitmapReadAccess::SetPixelOnData( sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor ) 488 { 489 DBG_ASSERT( pData, "Access is not valid!" ); 490 mFncSetPixel( pData, nX, rBitmapColor, maColorMask ); 491 } 492 493 // ------------------------------------------------------------------ 494 495 inline BitmapColor BitmapReadAccess::GetColor( long nY, long nX ) const 496 { 497 if( HasPalette() ) 498 return mpBuffer->maPalette[ GetPixelIndex( nY, nX ) ]; 499 else 500 return GetPixel( nY, nX ); 501 } 502 503 // ------------------------------------------------------------------ 504 505 inline sal_uInt8 BitmapReadAccess::GetLuminance( long nY, long nX ) const 506 { 507 return GetColor( nY, nX ).GetLuminance(); 508 } 509 510 // ------------------------------------------------------------------ 511 512 inline void BitmapWriteAccess::SetPalette( const BitmapPalette& rPalette ) 513 { 514 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 515 mpBuffer->maPalette = rPalette; 516 } 517 518 // ------------------------------------------------------------------ 519 520 inline void BitmapWriteAccess::SetPaletteEntryCount( sal_uInt16 nCount ) 521 { 522 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 523 mpBuffer->maPalette.SetEntryCount( nCount ); 524 } 525 526 // ------------------------------------------------------------------ 527 528 inline void BitmapWriteAccess::SetPaletteColor( sal_uInt16 nColor, const BitmapColor& rBitmapColor ) 529 { 530 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 531 DBG_ASSERT( HasPalette(), "Bitmap has no palette!" ); 532 mpBuffer->maPalette[ nColor ] = rBitmapColor; 533 } 534 535 // ------------------------------------------------------------------ 536 537 inline void BitmapWriteAccess::SetPixel( long nY, long nX, const BitmapColor& rBitmapColor ) 538 { 539 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 540 DBG_ASSERT( nX < mpBuffer->mnWidth, "x-coordinate out of range!" ); 541 DBG_ASSERT( nY < mpBuffer->mnHeight, "y-coordinate out of range!" ); 542 mFncSetPixel( mpScanBuf[ nY ], nX, rBitmapColor, maColorMask ); 543 } 544 545 inline void BitmapWriteAccess::SetPixelIndex( long nY, long nX, sal_uInt8 cIndex ) 546 { 547 SetPixel( nY, nX, BitmapColor( cIndex )); 548 } 549 550 // ------------------------------------------------------------------ 551 552 #endif // _SV_BMPACC_HXX 553