xref: /aoo42x/main/vcl/inc/vcl/bmpacc.hxx (revision cdf0e10c)
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