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