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
29AlphaMask::AlphaMask() = default;
30
31AlphaMask::AlphaMask( const Bitmap& rBitmap ) :
32 Bitmap( rBitmap )
33{
34 // no need to do any conversion if it is already an AlphaMask
35 if ( typeid(rBitmap) != typeid(AlphaMask) && !rBitmap.IsEmpty() )
37 assert( (IsEmpty() || getPixelFormat() == vcl::PixelFormat::N8_BPP) && "alpha bitmap should be 8bpp" );
38 assert( (IsEmpty() || HasGreyPalette8Bit()) && "alpha bitmap should have greyscale palette" );
39}
40
41AlphaMask::AlphaMask( const AlphaMask& ) = default;
42
43AlphaMask::AlphaMask( AlphaMask&& ) = default;
44
45AlphaMask::AlphaMask( const Size& rSizePixel, const sal_uInt8* pEraseTransparency )
46 : Bitmap(rSizePixel, vcl::PixelFormat::N8_BPP, &Bitmap::GetGreyPalette(256))
47{
48 if( pEraseTransparency )
49 {
50 sal_uInt8 nAlpha = 255 - *pEraseTransparency;
51 Bitmap::Erase( Color( nAlpha, nAlpha, nAlpha ) );
52 }
53 else
55}
56
57AlphaMask::~AlphaMask() = default;
58
60{
61 *static_cast<Bitmap*>(this) = rBitmap;
62
63 if( !rBitmap.IsEmpty() )
65
66 assert( getPixelFormat() == vcl::PixelFormat::N8_BPP && "alpha bitmap should be 8bpp" );
67 assert( HasGreyPalette8Bit() && "alpha bitmap should have greyscale palette" );
68
69 return *this;
70}
71
73{
74 return *this;
75}
76
78{
79 return ImplGetBitmap();
80}
81
82void AlphaMask::Erase( sal_uInt8 cTransparency )
83{
84 sal_uInt8 nAlpha = 255 - cTransparency;
85 Bitmap::Erase( Color( nAlpha, nAlpha, nAlpha ) );
86}
87
89{
90 std::shared_ptr<SalBitmap> xImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap());
91 if (xImpBmp->Create(*ImplGetSalBitmap()) && xImpBmp->AlphaBlendWith(*rOther.ImplGetSalBitmap()))
92 {
93 ImplSetSalBitmap(xImpBmp);
94 assert( getPixelFormat() == vcl::PixelFormat::N8_BPP && "alpha bitmap should be 8bpp" );
95 assert( HasGreyPalette8Bit() && "alpha bitmap should have greyscale palette" );
96 return;
97 }
98 Bitmap::ScopedReadAccess pOtherAcc(const_cast<AlphaMask&>(rOther));
99 AlphaScopedWriteAccess pAcc(*this);
100 assert (pOtherAcc && pAcc && pOtherAcc->GetBitCount() == 8 && pAcc->GetBitCount() == 8 && "cannot BlendWith this combination");
101 if (!(pOtherAcc && pAcc && pOtherAcc->GetBitCount() == 8 && pAcc->GetBitCount() == 8))
102 {
103 SAL_WARN("vcl", "cannot BlendWith this combination");
104 return;
105 }
106
107 const tools::Long nHeight = std::min(pOtherAcc->Height(), pAcc->Height());
108 const tools::Long nWidth = std::min(pOtherAcc->Width(), pAcc->Width());
109 for (tools::Long y = 0; y < nHeight; ++y)
110 {
111 Scanline scanline = pAcc->GetScanline( y );
112 ConstScanline otherScanline = pOtherAcc->GetScanline( y );
113 for (tools::Long x = 0; x < nWidth; ++x)
114 {
115 // Use sal_uInt16 for following multiplication
116 const sal_uInt16 nGrey1 = *scanline;
117 const sal_uInt16 nGrey2 = *otherScanline;
118 // Awkward calculation because the original used transparency, and to replicate
119 // the logic we need to translate into transparency, perform the original logic,
120 // then translate back to alpha.
121 auto tmp = 255 - ((255 - nGrey1) + (255 - nGrey2) - (255 - nGrey1) * (255 - nGrey2));
122 *scanline = static_cast<sal_uInt8>(tmp / 255);
123 ++scanline;
124 ++otherScanline;
125 }
126 }
127 pAcc.reset();
128 assert( getPixelFormat() == vcl::PixelFormat::N8_BPP && "alpha bitmap should be 8bpp" );
129 assert( HasGreyPalette8Bit() && "alpha bitmap should have greyscale palette" );
130}
131
133{
134 // no content, no alpha
135 if(IsEmpty())
136 return false;
137
138 ScopedReadAccess pAcc(const_cast<AlphaMask&>(*this));
139 const tools::Long nHeight(pAcc->Height());
140 const tools::Long nWidth(pAcc->Width());
141
142 // no content, no alpha
143 if(0 == nHeight || 0 == nWidth)
144 return false;
145
146 for (tools::Long y = 0; y < nHeight; ++y)
147 {
148 for (tools::Long x = 0; x < nWidth; ++x)
149 {
150 if (255 != pAcc->GetColor(y, x).GetRed())
151 {
152 return true;
153 }
154 }
155 }
156
157 return false;
158}
159
161{
162 if( pAccess )
163 {
164 Bitmap::ReleaseAccess( pAccess );
166 }
167 assert( getPixelFormat() == vcl::PixelFormat::N8_BPP && "alpha bitmap should be 8bpp" );
168 assert( HasGreyPalette8Bit() && "alpha bitmap should have greyscale palette" );
169}
170
171/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_uInt8 * ConstScanline
Definition: Scanline.hxx:27
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
AlphaMask & operator=(const Bitmap &rBitmap)
Definition: alpha.cxx:59
Bitmap const & GetBitmap() const
Definition: alpha.cxx:77
bool IsEmpty() const
void ReleaseAccess(BitmapReadAccess *pAccess)
Definition: alpha.cxx:160
virtual ~AlphaMask() override
SAL_DLLPRIVATE const Bitmap & ImplGetBitmap() const
Definition: alpha.cxx:72
void Erase(sal_uInt8 cTransparency)
Definition: alpha.cxx:82
bool hasAlpha() const
Definition: alpha.cxx:132
void BlendWith(const AlphaMask &rOther)
Definition: alpha.cxx:88
tools::Long Height() const
tools::Long Width() const
sal_uInt16 GetBitCount() const
Scanline GetScanline(tools::Long nY) const
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
bool HasGreyPalette8Bit() const
SAL_DLLPRIVATE void ImplSetSalBitmap(const std::shared_ptr< SalBitmap > &xImpBmp)
bool Convert(BmpConversion eConversion)
Convert bitmap format.
static void ReleaseAccess(BitmapInfoAccess *pAccess)
bool IsEmpty() const
bool Erase(const Color &rFillColor)
Fill the entire bitmap with the given color.
Definition: bitmappaint.cxx:34
vcl::PixelFormat getPixelFormat() const
constexpr ::Color COL_ALPHA_OPAQUE(0xff, 0xff, 0xff)
float y
float x
#define SAL_WARN(area, stream)
long Long
PixelFormat
Pixel format of the bitmap in bits per pixel.
Definition: BitmapTypes.hxx:20
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:77
unsigned char sal_uInt8