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