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