LibreOffice Module vcl (master)  1
alpha.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <tools/color.hxx>
21 #include <vcl/alpha.hxx>
22 
24 #include <salinst.hxx>
25 #include <svdata.hxx>
26 #include <salbmp.hxx>
27 #include <sal/log.hxx>
28 
29 AlphaMask::AlphaMask() = default;
30 
31 AlphaMask::AlphaMask( const Bitmap& rBitmap ) :
32  Bitmap( rBitmap )
33 {
34  if( !rBitmap.IsEmpty() )
36 }
37 
38 AlphaMask::AlphaMask( const AlphaMask& ) = default;
39 
40 AlphaMask::AlphaMask( AlphaMask&& ) = default;
41 
42 AlphaMask::AlphaMask( const Size& rSizePixel, const sal_uInt8* pEraseTransparency )
43  : Bitmap(rSizePixel, vcl::PixelFormat::N8_BPP, &Bitmap::GetGreyPalette(256))
44 {
45  if( pEraseTransparency )
46  Bitmap::Erase( Color( *pEraseTransparency, *pEraseTransparency, *pEraseTransparency ) );
47 }
48 
49 AlphaMask::~AlphaMask() = default;
50 
52 {
53  *static_cast<Bitmap*>(this) = rBitmap;
54 
55  if( !rBitmap.IsEmpty() )
57 
58  return *this;
59 }
60 
62 {
63  return *this;
64 }
65 
66 void AlphaMask::ImplSetBitmap( const Bitmap& rBitmap )
67 {
68  SAL_WARN_IF(rBitmap.getPixelFormat() != vcl::PixelFormat::N8_BPP, "vcl.gdi", "Bitmap should be 8bpp, not " << vcl::pixelFormatBitCount(rBitmap.getPixelFormat()) << "bpp" );
69  SAL_WARN_IF( !rBitmap.HasGreyPalette8Bit(), "vcl.gdi", "Bitmap isn't greyscale" );
70  *static_cast<Bitmap*>(this) = rBitmap;
71 }
72 
74 {
75  return ImplGetBitmap();
76 }
77 
78 void AlphaMask::Erase( sal_uInt8 cTransparency )
79 {
80  Bitmap::Erase( Color( cTransparency, cTransparency, cTransparency ) );
81 }
82 
83 void AlphaMask::Replace( sal_uInt8 cSearchTransparency, sal_uInt8 cReplaceTransparency )
84 {
85  AlphaScopedWriteAccess pAcc(*this);
86 
87  if( !(pAcc && pAcc->GetBitCount() == 8) )
88  return;
89 
90  const tools::Long nWidth = pAcc->Width(), nHeight = pAcc->Height();
91 
92  if( pAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal )
93  {
94  for( tools::Long nY = 0; nY < nHeight; nY++ )
95  {
96  Scanline pScan = pAcc->GetScanline( nY );
97 
98  for( tools::Long nX = 0; nX < nWidth; nX++, pScan++ )
99  {
100  if( *pScan == cSearchTransparency )
101  *pScan = cReplaceTransparency;
102  }
103  }
104  }
105  else
106  {
107  BitmapColor aReplace( cReplaceTransparency );
108 
109  for( tools::Long nY = 0; nY < nHeight; nY++ )
110  {
111  Scanline pScanline = pAcc->GetScanline(nY);
112  for( tools::Long nX = 0; nX < nWidth; nX++ )
113  {
114  if( pAcc->GetIndexFromData( pScanline, nX ) == cSearchTransparency )
115  pAcc->SetPixelOnData( pScanline, nX, aReplace );
116  }
117  }
118  }
119 }
120 
121 void AlphaMask::BlendWith(const Bitmap& rOther)
122 {
123  std::shared_ptr<SalBitmap> xImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap());
124  if (xImpBmp->Create(*ImplGetSalBitmap()) && xImpBmp->AlphaBlendWith(*rOther.ImplGetSalBitmap()))
125  {
126  ImplSetSalBitmap(xImpBmp);
127  return;
128  }
129  AlphaMask aOther(rOther); // to 8 bits
130  Bitmap::ScopedReadAccess pOtherAcc(aOther);
131  AlphaScopedWriteAccess pAcc(*this);
132  if (!(pOtherAcc && pAcc && pOtherAcc->GetBitCount() == 8 && pAcc->GetBitCount() == 8))
133  return;
134 
135  const tools::Long nHeight = std::min(pOtherAcc->Height(), pAcc->Height());
136  const tools::Long nWidth = std::min(pOtherAcc->Width(), pAcc->Width());
137  for (tools::Long y = 0; y < nHeight; ++y)
138  {
139  Scanline scanline = pAcc->GetScanline( y );
140  ConstScanline otherScanline = pOtherAcc->GetScanline( y );
141  for (tools::Long x = 0; x < nWidth; ++x)
142  {
143  // Use sal_uInt16 for following multiplication
144  const sal_uInt16 nGrey1 = *scanline;
145  const sal_uInt16 nGrey2 = *otherScanline;
146  *scanline = static_cast<sal_uInt8>(nGrey1 + nGrey2 - nGrey1 * nGrey2 / 255);
147  ++scanline;
148  ++otherScanline;
149  }
150  }
151 }
152 
154 {
155  if( pAccess )
156  {
157  Bitmap::ReleaseAccess( pAccess );
159  }
160 }
161 
162 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PixelFormat
Pixel format of the bitmap in bits per pixel.
Definition: BitmapTypes.hxx:19
tools::Long Height() const
void Replace(sal_uInt8 cSearchTransparency, sal_uInt8 cReplaceTransparency)
Definition: alpha.cxx:83
virtual ~AlphaMask() override
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
Definition: bitmap.hxx:522
Bitmap const & GetBitmap() const
Definition: alpha.cxx:73
long Long
sal_uInt16 GetBitCount() const
SAL_DLLPRIVATE void ImplSetBitmap(const Bitmap &rBitmap)
Definition: alpha.cxx:66
This template handles BitmapAccess the RAII way.
float x
bool HasGreyPalette8Bit() const
Scanline GetScanline(tools::Long nY) const
float y
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:74
void BlendWith(const Bitmap &rOther)
Definition: alpha.cxx:121
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
vcl::PixelFormat getPixelFormat() const
void Erase(sal_uInt8 cTransparency)
Definition: alpha.cxx:78
tools::Long Width() const
AlphaMask & operator=(const Bitmap &rBitmap)
Definition: alpha.cxx:51
static void ReleaseAccess(BitmapInfoAccess *pAccess)
void ReleaseAccess(BitmapReadAccess *pAccess)
Definition: alpha.cxx:153
const sal_uInt8 * ConstScanline
Definition: Scanline.hxx:27
SAL_DLLPRIVATE const Bitmap & ImplGetBitmap() const
Definition: alpha.cxx:61
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
bool Convert(BmpConversion eConversion)
Convert bitmap format.
bool IsEmpty() const
Definition: bitmap.hxx:547
constexpr sal_uInt16 pixelFormatBitCount(PixelFormat ePixelFormat)
Definition: BitmapTypes.hxx:35
bool Erase(const Color &rFillColor)
Fill the entire bitmap with the given color.
Definition: bitmappaint.cxx:34
SAL_DLLPRIVATE void ImplSetSalBitmap(const std::shared_ptr< SalBitmap > &xImpBmp)