Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / include / vcl / salbtype.hxx
blob7aa075aeed3cc9af44219c8390121dee1929c52f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_VCL_SALBTYPE_HXX
21 #define INCLUDED_VCL_SALBTYPE_HXX
23 #include <tools/debug.hxx>
24 #include <vcl/checksum.hxx>
25 #include <vcl/salgtype.hxx>
26 #include <tools/color.hxx>
27 #include <tools/helpers.hxx>
28 #include <tools/solar.h>
29 #include <vcl/dllapi.h>
30 #include <o3tl/typed_flags_set.hxx>
31 #include <vector>
33 typedef sal_uInt8* Scanline;
34 typedef const sal_uInt8* ConstScanline;
36 enum class ScanlineFormat {
37 NONE = 0x00000000,
39 N1BitMsbPal = 0x00000001,
40 N1BitLsbPal = 0x00000002,
42 N4BitMsnPal = 0x00000004,
43 N4BitLsnPal = 0x00000008,
45 N8BitPal = 0x00000010,
46 N8BitTcMask = 0x00000020,
48 N16BitTcMsbMask = 0x00000040,
49 N16BitTcLsbMask = 0x00000080,
51 N24BitTcBgr = 0x00000100,
52 N24BitTcRgb = 0x00000200,
54 N32BitTcAbgr = 0x00000800,
55 N32BitTcArgb = 0x00001000,
56 N32BitTcBgra = 0x00002000,
57 N32BitTcRgba = 0x00004000,
58 N32BitTcMask = 0x00008000,
60 TopDown = 0x00010000 // scanline adjustment
62 namespace o3tl {
63 template<> struct typed_flags<ScanlineFormat> : is_typed_flags<ScanlineFormat, 0x0001fbff> {};
65 inline ScanlineFormat RemoveScanline(ScanlineFormat nFormat) { return nFormat & ~ScanlineFormat::TopDown; }
68 #define MASK_TO_COLOR( d_nVal, d_RM, d_GM, d_BM, d_RS, d_GS, d_BS, d_Col ) \
69 const sal_uInt8 _def_cR = static_cast<sal_uInt8>( d_RS < 0 ? ( (d_nVal) & d_RM ) << -d_RS : ( (d_nVal) & d_RM ) >> d_RS ); \
70 const sal_uInt8 _def_cG = static_cast<sal_uInt8>( d_GS < 0 ? ( (d_nVal) & d_GM ) << -d_GS : ( (d_nVal) & d_GM ) >> d_GS ); \
71 const sal_uInt8 _def_cB = static_cast<sal_uInt8>( d_BS < 0 ? ( (d_nVal) & d_BM ) << -d_BS : ( (d_nVal) & d_BM ) >> d_BS ); \
72 d_Col = BitmapColor( (sal_uInt8) ( _def_cR | ( ( _def_cR & maR.mnOr ) >> maR.mnOrShift ) ), \
73 (sal_uInt8) ( _def_cG | ( ( _def_cG & maG.mnOr ) >> maG.mnOrShift ) ), \
74 (sal_uInt8) ( _def_cB | ( ( _def_cB & maB.mnOr ) >> maB.mnOrShift ) ) );
77 #define COLOR_TO_MASK( d_rCol, d_RM, d_GM, d_BM, d_RS, d_GS, d_BS, d_ALPHA ) \
78 ( ( ( ( d_RS < 0L ) ? ( (sal_uInt32) (d_rCol).GetRed() >> -d_RS ) : \
79 ( (sal_uInt32) (d_rCol).GetRed() << d_RS ) ) & d_RM ) | \
80 ( ( ( d_GS < 0L ) ? ( (sal_uInt32) (d_rCol).GetGreen() >> -d_GS ) : \
81 ( (sal_uInt32) (d_rCol).GetGreen() << d_GS ) ) & d_GM ) | \
82 ( ( ( d_BS < 0L ) ? ( (sal_uInt32) (d_rCol).GetBlue() >> -d_BS ) : \
83 ( (sal_uInt32) (d_rCol).GetBlue() << d_BS ) ) & d_BM ) | \
84 d_ALPHA )
87 class Color;
89 class VCL_DLLPUBLIC BitmapColor
91 private:
93 sal_uInt8 mcBlueOrIndex;
94 sal_uInt8 mcGreen;
95 sal_uInt8 mcRed;
96 sal_uInt8 mbIndex; // should be bool, but see above warning
98 public:
100 inline BitmapColor();
101 inline BitmapColor( sal_uInt8 cRed, sal_uInt8 cGreen, sal_uInt8 cBlue );
102 inline BitmapColor( const Color& rColor );
103 explicit inline BitmapColor( sal_uInt8 cIndex );
105 inline bool operator==( const BitmapColor& rBitmapColor ) const;
106 inline bool operator!=( const BitmapColor& rBitmapColor ) const;
108 inline bool IsIndex() const;
110 inline sal_uInt8 GetRed() const;
111 inline void SetRed( sal_uInt8 cRed );
113 inline sal_uInt8 GetGreen() const;
114 inline void SetGreen( sal_uInt8 cGreen );
116 inline sal_uInt8 GetBlue() const;
117 inline void SetBlue( sal_uInt8 cBlue );
119 inline sal_uInt8 GetIndex() const;
120 inline void SetIndex( sal_uInt8 cIndex );
122 operator Color() const;
124 inline sal_uInt8 GetBlueOrIndex() const;
126 inline BitmapColor& Invert();
128 inline sal_uInt8 GetLuminance() const;
130 inline BitmapColor& Merge( const BitmapColor& rColor, sal_uInt8 cTransparency );
132 inline sal_uInt16 GetColorError( const BitmapColor& rBitmapColor ) const;
135 template<typename charT, typename traits>
136 inline std::basic_ostream<charT, traits>& operator <<(std::basic_ostream<charT, traits>& rStream, const BitmapColor& rColor)
138 return rStream << "mcBlueOrIndex: " << (int)rColor.GetBlueOrIndex() << ", mcGreen: "
139 << (int)rColor.GetGreen() << ", mcRed: " << (int)rColor.GetRed() << ", mbIndex: " << (int)rColor.IsIndex();
142 class Palette;
144 class VCL_DLLPUBLIC BitmapPalette
146 friend class SalBitmap;
147 friend class BitmapAccess;
149 private:
151 std::vector<BitmapColor> maBitmapColor;
153 public:
155 SAL_DLLPRIVATE const BitmapColor* ImplGetColorBuffer() const
157 return maBitmapColor.data();
160 SAL_DLLPRIVATE BitmapColor* ImplGetColorBuffer()
162 return maBitmapColor.data();
165 BitmapChecksum GetChecksum() const
167 return vcl_get_checksum(0, maBitmapColor.data(), maBitmapColor.size() * sizeof(BitmapColor));
170 public:
172 BitmapPalette()
176 BitmapPalette(sal_uInt16 nCount)
177 : maBitmapColor(nCount)
181 bool operator==( const BitmapPalette& rBitmapPalette ) const
183 return maBitmapColor == rBitmapPalette.maBitmapColor;
186 bool operator!=(const BitmapPalette& rBitmapPalette) const
188 return !( *this == rBitmapPalette );
191 bool operator!()
193 return maBitmapColor.empty();
196 sal_uInt16 GetEntryCount() const
198 return maBitmapColor.size();
201 void SetEntryCount(sal_uInt16 nCount)
203 maBitmapColor.resize(nCount);
206 const BitmapColor& operator[](sal_uInt16 nIndex) const
208 assert(nIndex < maBitmapColor.size() && "Palette index is out of range");
209 return maBitmapColor[nIndex];
212 BitmapColor& operator[](sal_uInt16 nIndex)
214 assert(nIndex < maBitmapColor.size() && "Palette index is out of range");
215 return maBitmapColor[nIndex];
218 sal_uInt16 GetBestIndex(const BitmapColor& rCol) const
220 sal_uInt16 nRetIndex = 0;
222 if (!maBitmapColor.empty())
224 for (size_t j = 0; j < maBitmapColor.size(); ++j)
226 if (rCol == maBitmapColor[j])
228 return j;
232 sal_uInt16 nLastErr = SAL_MAX_UINT16;
233 for (size_t i = 0; i < maBitmapColor.size(); ++i)
235 const sal_uInt16 nActErr = rCol.GetColorError(maBitmapColor[i]);
236 if ( nActErr < nLastErr )
238 nLastErr = nActErr;
239 nRetIndex = i;
244 return nRetIndex;
247 bool IsGreyPalette() const;
250 struct VCL_DLLPUBLIC ColorMaskElement
252 sal_uInt32 mnMask;
253 int mnShift;
254 int mnOrShift;
255 sal_uInt8 mnOr;
256 explicit ColorMaskElement(sal_uInt32 nMask = 0)
257 : mnMask(nMask)
258 , mnShift(0)
259 , mnOrShift(0)
260 , mnOr(0)
263 bool CalcMaskShift()
265 if (mnMask == 0)
266 return true;
268 // from which bit starts the mask?
269 int nShift = 31;
271 while( nShift >= 0 && !( mnMask & ( 1 << nShift ) ) )
272 --nShift;
274 mnShift = nShift - 7;
275 int nLen = 0;
277 // XXX determine number of bits set => walk right until null
278 while( nShift >= 0 && ( mnMask & ( 1 << nShift ) ) )
280 nShift--;
281 nLen++;
284 if (nLen > 8) // mask length must be 8 bits or less
285 return false;
287 mnOrShift = 8 - nLen;
288 mnOr = static_cast<sal_uInt8>( ( 0xFF >> nLen ) << mnOrShift );
290 return true;
294 class VCL_DLLPUBLIC ColorMask
296 ColorMaskElement maR;
297 ColorMaskElement maG;
298 ColorMaskElement maB;
300 public:
302 ColorMask(const ColorMaskElement& rRedMask = ColorMaskElement(),
303 const ColorMaskElement& rGreenMask = ColorMaskElement(),
304 const ColorMaskElement& rBlueMask = ColorMaskElement())
305 : maR(rRedMask)
306 , maG(rGreenMask)
307 , maB(rBlueMask)
311 inline sal_uInt32 GetRedMask() const;
312 inline sal_uInt32 GetGreenMask() const;
313 inline sal_uInt32 GetBlueMask() const;
315 inline void GetColorFor8Bit( BitmapColor& rColor, const sal_uInt8* pPixel ) const;
316 inline void SetColorFor8Bit( const BitmapColor& rColor, sal_uInt8* pPixel ) const;
318 inline void GetColorFor16BitMSB( BitmapColor& rColor, const sal_uInt8* pPixel ) const;
319 inline void SetColorFor16BitMSB( const BitmapColor& rColor, sal_uInt8* pPixel ) const;
320 inline void GetColorFor16BitLSB( BitmapColor& rColor, const sal_uInt8* pPixel ) const;
321 inline void SetColorFor16BitLSB( const BitmapColor& rColor, sal_uInt8* pPixel ) const;
323 inline void GetColorFor32Bit( BitmapColor& rColor, const sal_uInt8* pPixel ) const;
324 inline void GetColorAndAlphaFor32Bit( BitmapColor& rColor, sal_uInt8& rAlpha, const sal_uInt8* pPixel ) const;
325 inline void SetColorFor32Bit( const BitmapColor& rColor, sal_uInt8* pPixel ) const;
328 struct VCL_DLLPUBLIC BitmapBuffer
330 ScanlineFormat mnFormat;
331 long mnWidth;
332 long mnHeight;
333 long mnScanlineSize;
334 sal_uInt16 mnBitCount;
335 ColorMask maColorMask;
336 BitmapPalette maPalette;
337 sal_uInt8* mpBits;
340 enum class BitmapAccessMode
342 Info,
343 Read,
344 Write
347 VCL_DLLPUBLIC BitmapBuffer* StretchAndConvert(
348 const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect,
349 ScanlineFormat nDstBitmapFormat, const BitmapPalette* pDstPal = nullptr, const ColorMask* pDstMask = nullptr );
351 inline BitmapColor::BitmapColor() :
352 mcBlueOrIndex ( 0 ),
353 mcGreen ( 0 ),
354 mcRed ( 0 ),
355 mbIndex ( sal_uInt8(false) )
359 inline BitmapColor::BitmapColor( sal_uInt8 cRed, sal_uInt8 cGreen, sal_uInt8 cBlue ) :
360 mcBlueOrIndex ( cBlue ),
361 mcGreen ( cGreen ),
362 mcRed ( cRed ),
363 mbIndex ( sal_uInt8(false) )
367 inline BitmapColor::BitmapColor( const Color& rColor ) :
368 mcBlueOrIndex ( rColor.GetBlue() ),
369 mcGreen ( rColor.GetGreen() ),
370 mcRed ( rColor.GetRed() ),
371 mbIndex ( sal_uInt8(false) )
375 inline BitmapColor::BitmapColor( sal_uInt8 cIndex ) :
376 mcBlueOrIndex ( cIndex ),
377 mcGreen ( 0 ),
378 mcRed ( 0 ),
379 mbIndex ( sal_uInt8(true) )
383 inline bool BitmapColor::operator==( const BitmapColor& rBitmapColor ) const
385 return( ( mcBlueOrIndex == rBitmapColor.mcBlueOrIndex ) &&
386 ( mbIndex ? bool(rBitmapColor.mbIndex) :
387 ( mcGreen == rBitmapColor.mcGreen && mcRed == rBitmapColor.mcRed ) ) );
390 inline bool BitmapColor::operator!=( const BitmapColor& rBitmapColor ) const
392 return !( *this == rBitmapColor );
395 inline bool BitmapColor::IsIndex() const
397 return mbIndex;
400 inline sal_uInt8 BitmapColor::GetRed() const
402 assert( !mbIndex && "Pixel represents index into colortable" );
403 return mcRed;
406 inline void BitmapColor::SetRed( sal_uInt8 cRed )
408 assert( !mbIndex && "Pixel represents index into colortable" );
409 mcRed = cRed;
412 inline sal_uInt8 BitmapColor::GetGreen() const
414 assert( !mbIndex && "Pixel represents index into colortable" );
415 return mcGreen;
418 inline void BitmapColor::SetGreen( sal_uInt8 cGreen )
420 assert( !mbIndex && "Pixel represents index into colortable" );
421 mcGreen = cGreen;
424 inline sal_uInt8 BitmapColor::GetBlue() const
426 assert( !mbIndex && "Pixel represents index into colortable" );
427 return mcBlueOrIndex;
430 inline void BitmapColor::SetBlue( sal_uInt8 cBlue )
432 assert( !mbIndex && "Pixel represents index into colortable" );
433 mcBlueOrIndex = cBlue;
436 inline sal_uInt8 BitmapColor::GetIndex() const
438 assert( mbIndex && "Pixel represents color values" );
439 return mcBlueOrIndex;
442 inline void BitmapColor::SetIndex( sal_uInt8 cIndex )
444 assert( mbIndex && "Pixel represents color values" );
445 mcBlueOrIndex = cIndex;
448 inline BitmapColor::operator Color() const
450 assert( !mbIndex && "Pixel represents index into colortable" );
451 return Color( mcRed, mcGreen, mcBlueOrIndex );
454 inline sal_uInt8 BitmapColor::GetBlueOrIndex() const
456 // #i47518# Yield a value regardless of mbIndex
457 return mcBlueOrIndex;
460 inline BitmapColor& BitmapColor::Invert()
462 assert( !mbIndex && "Pixel represents index into colortable" );
463 mcBlueOrIndex = ~mcBlueOrIndex;
464 mcGreen = ~mcGreen;
465 mcRed = ~mcRed;
467 return *this;
470 inline sal_uInt8 BitmapColor::GetLuminance() const
472 assert( !mbIndex && "Pixel represents index into colortable" );
473 return (static_cast<unsigned long>(mcBlueOrIndex) * 28UL + static_cast<unsigned long>(mcGreen) * 151UL + static_cast<unsigned long>(mcRed) * 77UL) >> 8;
477 inline BitmapColor& BitmapColor::Merge( const BitmapColor& rBitmapColor, sal_uInt8 cTransparency )
479 assert( !mbIndex && "Pixel represents index into colortable" );
480 assert( !rBitmapColor.mbIndex && "Pixel represents index into colortable" );
481 mcBlueOrIndex = COLOR_CHANNEL_MERGE( mcBlueOrIndex, rBitmapColor.mcBlueOrIndex, cTransparency );
482 mcGreen = COLOR_CHANNEL_MERGE( mcGreen, rBitmapColor.mcGreen, cTransparency );
483 mcRed = COLOR_CHANNEL_MERGE( mcRed, rBitmapColor.mcRed, cTransparency );
485 return *this;
489 inline sal_uInt16 BitmapColor::GetColorError( const BitmapColor& rBitmapColor ) const
491 assert( !mbIndex && "Pixel represents index into colortable" );
492 assert( !rBitmapColor.mbIndex && "Pixel represents index into colortable" );
493 return static_cast<sal_uInt16>(
494 abs( static_cast<int>(mcBlueOrIndex) - static_cast<int>(rBitmapColor.mcBlueOrIndex) ) +
495 abs( static_cast<int>(mcGreen) - static_cast<int>(rBitmapColor.mcGreen) ) +
496 abs( static_cast<int>(mcRed) - static_cast<int>(rBitmapColor.mcRed) ) );
499 inline sal_uInt32 ColorMask::GetRedMask() const
501 return maR.mnMask;
504 inline sal_uInt32 ColorMask::GetGreenMask() const
506 return maG.mnMask;
509 inline sal_uInt32 ColorMask::GetBlueMask() const
511 return maB.mnMask;
514 inline void ColorMask::GetColorFor8Bit( BitmapColor& rColor, const sal_uInt8* pPixel ) const
516 const sal_uInt32 nVal = *pPixel;
517 MASK_TO_COLOR( nVal, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maR.mnShift, rColor );
520 inline void ColorMask::SetColorFor8Bit( const BitmapColor& rColor, sal_uInt8* pPixel ) const
522 *pPixel = (sal_uInt8) COLOR_TO_MASK( rColor, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, 0/*nAlphaChannel*/ );
525 inline void ColorMask::GetColorFor16BitMSB( BitmapColor& rColor, const sal_uInt8* pPixel ) const
527 const sal_uInt32 nVal = pPixel[ 1 ] | ( (sal_uInt32) pPixel[ 0 ] << 8UL );
529 MASK_TO_COLOR( nVal, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, rColor );
532 inline void ColorMask::SetColorFor16BitMSB( const BitmapColor& rColor, sal_uInt8* pPixel ) const
534 const sal_uInt16 nVal = (sal_uInt16)COLOR_TO_MASK( rColor, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, 0/*nAlphaChannel*/ );
536 pPixel[ 0 ] = (sal_uInt8)(nVal >> 8U);
537 pPixel[ 1 ] = (sal_uInt8) nVal;
540 inline void ColorMask::GetColorFor16BitLSB( BitmapColor& rColor, const sal_uInt8* pPixel ) const
542 const sal_uInt32 nVal = pPixel[ 0 ] | ( (sal_uInt32) pPixel[ 1 ] << 8UL );
544 MASK_TO_COLOR( nVal, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, rColor );
547 inline void ColorMask::SetColorFor16BitLSB( const BitmapColor& rColor, sal_uInt8* pPixel ) const
549 const sal_uInt16 nVal = (sal_uInt16)COLOR_TO_MASK( rColor, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, 0/*nAlphaChannel*/ );
551 pPixel[ 0 ] = (sal_uInt8) nVal;
552 pPixel[ 1 ] = (sal_uInt8)(nVal >> 8U);
555 inline void ColorMask::GetColorFor32Bit( BitmapColor& rColor, const sal_uInt8* pPixel ) const
557 const sal_uInt32 nVal = (sal_uInt32) pPixel[ 0 ] | ( (sal_uInt32) pPixel[ 1 ] << 8UL ) |
558 ( (sal_uInt32) pPixel[ 2 ] << 16UL ) | ( (sal_uInt32) pPixel[ 3 ] << 24UL );
560 MASK_TO_COLOR( nVal, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, rColor );
563 inline void ColorMask::GetColorAndAlphaFor32Bit( BitmapColor& rColor, sal_uInt8& rAlpha, const sal_uInt8* pPixel ) const
565 const sal_uInt32 nVal = (sal_uInt32) pPixel[ 0 ] | ( (sal_uInt32) pPixel[ 1 ] << 8UL ) |
566 ( (sal_uInt32) pPixel[ 2 ] << 16UL ) | ( (sal_uInt32) pPixel[ 3 ] << 24UL );
567 rAlpha = (sal_uInt8)(nVal >> 24);
569 MASK_TO_COLOR( nVal, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, rColor );
572 inline void ColorMask::SetColorFor32Bit( const BitmapColor& rColor, sal_uInt8* pPixel ) const
574 const sal_uInt32 nVal = COLOR_TO_MASK( rColor, maR.mnMask, maG.mnMask, maB.mnMask, maR.mnShift, maG.mnShift, maB.mnShift, 0/*nAlphaChannel*/ );
575 pPixel[ 0 ] = (sal_uInt8) nVal;
576 pPixel[ 1 ] = (sal_uInt8) ( nVal >> 8UL );
577 pPixel[ 2 ] = (sal_uInt8) ( nVal >> 16UL );
578 pPixel[ 3 ] = (sal_uInt8) ( nVal >> 24UL );
581 #endif // INCLUDED_VCL_SALBTYPE_HXX
583 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */