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