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 GetLuminance( long nY, long nX ) const; 173 }; 174 175 // --------------------- 176 // - BitmapWriteAccess - 177 // --------------------- 178 179 class VCL_DLLPUBLIC BitmapWriteAccess : public BitmapReadAccess 180 { 181 public: 182 183 BitmapWriteAccess( Bitmap& rBitmap ); 184 virtual ~BitmapWriteAccess(); 185 186 void CopyScanline( long nY, const BitmapReadAccess& rReadAcc ); 187 void CopyScanline( long nY, ConstScanline aSrcScanline, 188 sal_uLong nSrcScanlineFormat, sal_uLong nSrcScanlineSize ); 189 190 void CopyBuffer( const BitmapReadAccess& rReadAcc ); 191 192 inline void SetPalette( const BitmapPalette& rPalette ); 193 inline void SetPaletteEntryCount( sal_uInt16 nCount ); 194 inline void SetPaletteColor( sal_uInt16 nColor, const BitmapColor& rBitmapColor ); 195 196 inline void SetPixel( long nY, long nX, const BitmapColor& rBitmapColor ); 197 198 void SetLineColor(); 199 void SetLineColor( const Color& rColor ); 200 Color GetLineColor() const; 201 202 void SetFillColor(); 203 void SetFillColor( const Color& rColor ); 204 Color GetFillColor() const; 205 206 void Erase( const Color& rColor ); 207 208 void DrawLine( const Point& rStart, const Point& rEnd ); 209 210 void FillRect( const Rectangle& rRect ); 211 void DrawRect( const Rectangle& rRect ); 212 213 void FillPolygon( const Polygon& rPoly ); 214 void DrawPolygon( const Polygon& rPoly ); 215 216 void FillPolyPolygon( const PolyPolygon& rPoly ); 217 void DrawPolyPolygon( const PolyPolygon& rPolyPoly ); 218 219 private: 220 221 BitmapColor* mpLineColor; 222 BitmapColor* mpFillColor; 223 224 BitmapWriteAccess() {} 225 BitmapWriteAccess( const BitmapWriteAccess& ) : BitmapReadAccess() {} 226 BitmapWriteAccess& operator=( const BitmapWriteAccess& ) { return *this; } 227 }; 228 229 // ------------------- 230 // - Accessor Helper - 231 // ------------------- 232 233 /** This template handles BitmapAccess the RAII way. 234 235 Please don't use directly, but the ready-made typedefs for 236 BitmapReadAccess and BitmapWriteAccess below. 237 */ 238 template < class Access > class ScopedBitmapAccess 239 { 240 public: 241 ScopedBitmapAccess( Access* pAccess, 242 Bitmap& rBitmap ) : 243 mpAccess( pAccess ), 244 mrBitmap( rBitmap ) 245 { 246 } 247 248 ~ScopedBitmapAccess() 249 { 250 mrBitmap.ReleaseAccess( mpAccess ); 251 } 252 253 Access* get() { return mpAccess; } 254 const Access* get() const { return mpAccess; } 255 256 Access* operator->() { return mpAccess; } 257 const Access* operator->() const { return mpAccess; } 258 259 Access& operator*() { return *mpAccess; } 260 const Access& operator*() const { return *mpAccess; } 261 262 private: 263 Access* mpAccess; 264 Bitmap& mrBitmap; 265 }; 266 267 /** This wrapper handles BitmapReadAccess the RAII way. 268 269 Use as follows: 270 Bitmap aBitmap 271 ScopedBitmapReadAccess pReadAccess( aBitmap.AcquireReadAccess(), aBitmap ); 272 pReadAccess->SetPixel()... 273 274 @attention for practical reasons, ScopedBitmapReadAccess stores a 275 reference to the provided bitmap, thus, make sure that the bitmap 276 specified at construction time lives at least as long as the 277 ScopedBitmapReadAccess. 278 */ 279 typedef ScopedBitmapAccess< BitmapReadAccess > ScopedBitmapReadAccess; 280 281 /** This wrapper handles BitmapWriteAccess the RAII way. 282 283 Use as follows: 284 Bitmap aBitmap 285 ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(), aBitmap ); 286 pWriteAccess->SetPixel()... 287 288 @attention for practical reasons, ScopedBitmapWriteAccess stores a 289 reference to the provided bitmap, thus, make sure that the bitmap 290 specified at construction time lives at least as long as the 291 ScopedBitmapWriteAccess. 292 */ 293 typedef ScopedBitmapAccess< BitmapWriteAccess > ScopedBitmapWriteAccess; 294 295 // ----------- 296 // - Inlines - 297 // ----------- 298 299 inline sal_Bool BitmapReadAccess::operator!() const 300 { 301 return( mpBuffer == NULL ); 302 } 303 304 // ------------------------------------------------------------------ 305 306 inline long BitmapReadAccess::Width() const 307 { 308 return( mpBuffer ? mpBuffer->mnWidth : 0L ); 309 } 310 311 // ------------------------------------------------------------------ 312 313 inline long BitmapReadAccess::Height() const 314 { 315 return( mpBuffer ? mpBuffer->mnHeight : 0L ); 316 } 317 318 // ------------------------------------------------------------------ 319 320 inline Point BitmapReadAccess::TopLeft() const 321 { 322 return Point(); 323 } 324 325 // ------------------------------------------------------------------ 326 327 inline Point BitmapReadAccess::BottomRight() const 328 { 329 return Point( Width() - 1L, Height() - 1L ); 330 } 331 332 // ------------------------------------------------------------------ 333 334 inline sal_Bool BitmapReadAccess::IsTopDown() const 335 { 336 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 337 return( mpBuffer ? sal::static_int_cast<sal_Bool>( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) : sal_False ); 338 } 339 340 // ------------------------------------------------------------------ 341 342 inline sal_Bool BitmapReadAccess::IsBottomUp() const 343 { 344 return !IsTopDown(); 345 } 346 347 // ------------------------------------------------------------------ 348 349 inline sal_uLong BitmapReadAccess::GetScanlineFormat() const 350 { 351 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 352 return( mpBuffer ? BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) : 0UL ); 353 } 354 355 // ------------------------------------------------------------------ 356 357 inline sal_uLong BitmapReadAccess::GetScanlineSize() const 358 { 359 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 360 return( mpBuffer ? mpBuffer->mnScanlineSize : 0UL ); 361 } 362 363 // ------------------------------------------------------------------ 364 365 inline sal_uInt16 BitmapReadAccess::GetBitCount() const 366 { 367 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 368 return( mpBuffer ? mpBuffer->mnBitCount : 0 ); 369 } 370 371 // ------------------------------------------------------------------ 372 373 inline BitmapColor BitmapReadAccess::GetBestMatchingColor( const BitmapColor& rBitmapColor ) 374 { 375 if( HasPalette() ) 376 return BitmapColor( (sal_uInt8) GetBestPaletteIndex( rBitmapColor ) ); 377 else 378 return rBitmapColor; 379 } 380 381 // ------------------------------------------------------------------ 382 383 inline Scanline BitmapReadAccess::GetBuffer() const 384 { 385 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 386 return( mpBuffer ? mpBuffer->mpBits : NULL ); 387 } 388 389 // ------------------------------------------------------------------ 390 391 inline Scanline BitmapReadAccess::GetScanline( long nY ) const 392 { 393 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 394 DBG_ASSERT( nY < mpBuffer->mnHeight, "y-coordinate out of range!" ); 395 return( mpBuffer ? mpScanBuf[ nY ] : NULL ); 396 } 397 398 // ------------------------------------------------------------------ 399 400 inline sal_Bool BitmapReadAccess::HasPalette() const 401 { 402 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 403 return( mpBuffer && !!mpBuffer->maPalette ); 404 } 405 406 // ------------------------------------------------------------------ 407 408 inline const BitmapPalette& BitmapReadAccess::GetPalette() const 409 { 410 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 411 return mpBuffer->maPalette; 412 } 413 414 // ------------------------------------------------------------------ 415 416 inline sal_uInt16 BitmapReadAccess::GetPaletteEntryCount() const 417 { 418 DBG_ASSERT( HasPalette(), "Bitmap has no palette!" ); 419 return( HasPalette() ? mpBuffer->maPalette.GetEntryCount() : 0 ); 420 } 421 422 // ------------------------------------------------------------------ 423 424 inline const BitmapColor& BitmapReadAccess::GetPaletteColor( sal_uInt16 nColor ) const 425 { 426 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 427 DBG_ASSERT( HasPalette(), "Bitmap has no palette!" ); 428 return mpBuffer->maPalette[ nColor ]; 429 } 430 431 // ------------------------------------------------------------------ 432 433 inline const BitmapColor& BitmapReadAccess::GetBestPaletteColor( const BitmapColor& rBitmapColor ) const 434 { 435 return GetPaletteColor( GetBestPaletteIndex( rBitmapColor ) ); 436 } 437 438 // ------------------------------------------------------------------ 439 440 inline sal_Bool BitmapReadAccess::HasColorMask() const 441 { 442 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 443 const sal_uLong nFormat = BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ); 444 445 return( nFormat == BMP_FORMAT_8BIT_TC_MASK || 446 nFormat == BMP_FORMAT_16BIT_TC_MSB_MASK || 447 nFormat == BMP_FORMAT_16BIT_TC_LSB_MASK || 448 nFormat == BMP_FORMAT_24BIT_TC_MASK || 449 nFormat == BMP_FORMAT_32BIT_TC_MASK ); 450 } 451 452 // ------------------------------------------------------------------ 453 454 inline ColorMask& BitmapReadAccess::GetColorMask() const 455 { 456 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 457 return mpBuffer->maColorMask; 458 } 459 460 // ------------------------------------------------------------------ 461 462 inline BitmapColor BitmapReadAccess::GetPixel( long nY, long nX ) const 463 { 464 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 465 DBG_ASSERT( nX < mpBuffer->mnWidth, "x-coordinate out of range!" ); 466 DBG_ASSERT( nY < mpBuffer->mnHeight, "y-coordinate out of range!" ); 467 return mFncGetPixel( mpScanBuf[ nY ], nX, maColorMask ); 468 } 469 470 // ------------------------------------------------------------------ 471 472 inline BitmapColor BitmapReadAccess::GetPixelFromData( const sal_uInt8* pData, long nX ) const 473 { 474 DBG_ASSERT( pData, "Access is not valid!" ); 475 return mFncGetPixel( pData, nX, maColorMask ); 476 } 477 478 // ------------------------------------------------------------------ 479 480 inline void BitmapReadAccess::SetPixelOnData( sal_uInt8* pData, long nX, const BitmapColor& rBitmapColor ) 481 { 482 DBG_ASSERT( pData, "Access is not valid!" ); 483 mFncSetPixel( pData, nX, rBitmapColor, maColorMask ); 484 } 485 486 // ------------------------------------------------------------------ 487 488 inline BitmapColor BitmapReadAccess::GetColor( long nY, long nX ) const 489 { 490 if( !!mpBuffer->maPalette ) 491 { 492 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 493 return mpBuffer->maPalette[ GetPixel( nY, nX ).GetIndex() ]; 494 } 495 else 496 return GetPixel( nY, nX ); 497 } 498 499 // ------------------------------------------------------------------ 500 501 inline sal_uInt8 BitmapReadAccess::GetLuminance( long nY, long nX ) const 502 { 503 return GetColor( nY, nX ).GetLuminance(); 504 } 505 506 // ------------------------------------------------------------------ 507 508 inline void BitmapWriteAccess::SetPalette( const BitmapPalette& rPalette ) 509 { 510 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 511 mpBuffer->maPalette = rPalette; 512 } 513 514 // ------------------------------------------------------------------ 515 516 inline void BitmapWriteAccess::SetPaletteEntryCount( sal_uInt16 nCount ) 517 { 518 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 519 mpBuffer->maPalette.SetEntryCount( nCount ); 520 } 521 522 // ------------------------------------------------------------------ 523 524 inline void BitmapWriteAccess::SetPaletteColor( sal_uInt16 nColor, const BitmapColor& rBitmapColor ) 525 { 526 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 527 DBG_ASSERT( HasPalette(), "Bitmap has no palette!" ); 528 mpBuffer->maPalette[ nColor ] = rBitmapColor; 529 } 530 531 // ------------------------------------------------------------------ 532 533 inline void BitmapWriteAccess::SetPixel( long nY, long nX, const BitmapColor& rBitmapColor ) 534 { 535 DBG_ASSERT( mpBuffer, "Access is not valid!" ); 536 DBG_ASSERT( nX < mpBuffer->mnWidth, "x-coordinate out of range!" ); 537 DBG_ASSERT( nY < mpBuffer->mnHeight, "y-coordinate out of range!" ); 538 mFncSetPixel( mpScanBuf[ nY ], nX, rBitmapColor, maColorMask ); 539 } 540 541 #endif // _SV_BMPACC_HXX 542