Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <tools/debug.hxx>
30 : : #include <vcl/bmpacc.hxx>
31 : : #include <tools/color.hxx>
32 : : #include <vcl/alpha.hxx>
33 : :
34 : : // -------------
35 : : // - AlphaMask -
36 : : // -------------
37 : :
38 : 275465 : AlphaMask::AlphaMask()
39 : : {
40 : 275465 : }
41 : :
42 : 14774 : AlphaMask::AlphaMask( const Bitmap& rBitmap ) :
43 : 14774 : Bitmap( rBitmap )
44 : : {
45 [ + + ]: 14774 : if( !!rBitmap )
46 [ + - ]: 14559 : Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
47 : 14774 : }
48 : :
49 : 275452 : AlphaMask::AlphaMask( const AlphaMask& rAlphaMask ) :
50 : 275452 : Bitmap( rAlphaMask )
51 : : {
52 : 275452 : }
53 : :
54 : 23960 : AlphaMask::AlphaMask( const Size& rSizePixel, sal_uInt8* pEraseTransparency ) :
55 : 23960 : Bitmap( rSizePixel, 8, &Bitmap::GetGreyPalette( 256 ) )
56 : : {
57 [ + + ]: 23960 : if( pEraseTransparency )
58 [ + - ]: 3759 : Bitmap::Erase( Color( *pEraseTransparency, *pEraseTransparency, *pEraseTransparency ) );
59 : 23960 : }
60 : :
61 : 589651 : AlphaMask::~AlphaMask()
62 : : {
63 : 589651 : }
64 : :
65 : 0 : AlphaMask& AlphaMask::operator=( const Bitmap& rBitmap )
66 : : {
67 : 0 : *(Bitmap*) this = rBitmap;
68 : :
69 [ # # ]: 0 : if( !!rBitmap )
70 : 0 : Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
71 : :
72 : 0 : return *this;
73 : : }
74 : :
75 : 53395 : const Bitmap& AlphaMask::ImplGetBitmap() const
76 : : {
77 : 53395 : return( (const Bitmap&) *this );
78 : : }
79 : :
80 : 275465 : void AlphaMask::ImplSetBitmap( const Bitmap& rBitmap )
81 : : {
82 : : DBG_ASSERT( ( 8 == rBitmap.GetBitCount() ) && rBitmap.HasGreyPalette(), "AlphaMask::ImplSetBitmap: invalid bitmap" );
83 : 275465 : *(Bitmap*) this = rBitmap;
84 : 275465 : }
85 : :
86 : 1926 : Bitmap AlphaMask::GetBitmap() const
87 : : {
88 : 1926 : return ImplGetBitmap();
89 : : }
90 : :
91 : 1101 : sal_Bool AlphaMask::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
92 : : const AlphaMask* pAlphaSrc )
93 : : {
94 : : // Note: this code is copied from Bitmap::CopyPixel but avoids any palette lookups
95 : : // this optimization is possible because the palettes of AlphaMasks are always identical (8bit GreyPalette, see ctor)
96 : :
97 [ + - ]: 1101 : const Size aSizePix( GetSizePixel() );
98 : 1101 : Rectangle aRectDst( rRectDst );
99 : 1101 : sal_Bool bRet = sal_False;
100 : :
101 [ + - ][ + - ]: 1101 : aRectDst.Intersection( Rectangle( Point(), aSizePix ) );
102 : :
103 [ + - ][ + - ]: 1101 : if( !aRectDst.IsEmpty() )
104 : : {
105 [ + - ][ + - ]: 1101 : if( pAlphaSrc && ( *pAlphaSrc != *this ) )
[ + - ]
106 : : {
107 : 1101 : Bitmap* pSrc = (Bitmap*) pAlphaSrc;
108 [ + - ]: 1101 : const Size aCopySizePix( pSrc->GetSizePixel() );
109 : 1101 : Rectangle aRectSrc( rRectSrc );
110 : :
111 [ + - ][ + - ]: 1101 : aRectSrc.Intersection( Rectangle( Point(), aCopySizePix ) );
112 : :
113 [ + - ][ + - ]: 1101 : if( !aRectSrc.IsEmpty() )
114 : : {
115 [ + - ]: 1101 : BitmapReadAccess* pReadAcc = pSrc->AcquireReadAccess();
116 : :
117 [ + - ]: 1101 : if( pReadAcc )
118 : : {
119 [ + - ]: 1101 : BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
120 : :
121 [ + - ]: 1101 : if( pWriteAcc )
122 : : {
123 [ + - ][ + - ]: 1101 : const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
124 [ + - ][ + - ]: 1101 : const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
125 : 1101 : const long nSrcEndX = aRectSrc.Left() + nWidth;
126 : 1101 : const long nSrcEndY = aRectSrc.Top() + nHeight;
127 : 1101 : long nDstY = aRectDst.Top();
128 : :
129 [ + + ]: 9909 : for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
130 [ + + ]: 79272 : for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
131 [ + - ][ + - ]: 70464 : pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPixel( nSrcY, nSrcX ) );
132 : :
133 [ + - ]: 1101 : ReleaseAccess( pWriteAcc );
134 [ + - ][ + - ]: 1101 : bRet = ( nWidth > 0L ) && ( nHeight > 0L );
135 : : }
136 : :
137 [ + - ]: 1101 : pSrc->ReleaseAccess( pReadAcc );
138 : : }
139 : : }
140 : : }
141 : : else
142 : : {
143 : 0 : Rectangle aRectSrc( rRectSrc );
144 : :
145 [ # # ][ # # ]: 0 : aRectSrc.Intersection( Rectangle( Point(), aSizePix ) );
146 : :
147 [ # # ][ # # ]: 0 : if( !aRectSrc.IsEmpty() && ( aRectSrc != aRectDst ) )
[ # # ][ # # ]
[ # # ]
148 : : {
149 [ # # ]: 0 : BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
150 : :
151 [ # # ]: 0 : if( pWriteAcc )
152 : : {
153 [ # # ][ # # ]: 0 : const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
154 [ # # ][ # # ]: 0 : const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
155 : 0 : const long nSrcX = aRectSrc.Left();
156 : 0 : const long nSrcY = aRectSrc.Top();
157 : 0 : const long nSrcEndX1 = nSrcX + nWidth - 1L;
158 : 0 : const long nSrcEndY1 = nSrcY + nHeight - 1L;
159 : 0 : const long nDstX = aRectDst.Left();
160 : 0 : const long nDstY = aRectDst.Top();
161 : 0 : const long nDstEndX1 = nDstX + nWidth - 1L;
162 : 0 : const long nDstEndY1 = nDstY + nHeight - 1L;
163 : :
164 [ # # ][ # # ]: 0 : if( ( nDstX <= nSrcX ) && ( nDstY <= nSrcY ) )
165 : : {
166 [ # # ]: 0 : for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
167 [ # # ]: 0 : for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
168 [ # # ][ # # ]: 0 : pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
169 : : }
170 [ # # ][ # # ]: 0 : else if( ( nDstX <= nSrcX ) && ( nDstY >= nSrcY ) )
171 : : {
172 [ # # ]: 0 : for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
173 [ # # ]: 0 : for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
174 [ # # ][ # # ]: 0 : pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
175 : : }
176 [ # # ][ # # ]: 0 : else if( ( nDstX >= nSrcX ) && ( nDstY <= nSrcY ) )
177 : : {
178 [ # # ]: 0 : for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
179 [ # # ]: 0 : for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
180 [ # # ][ # # ]: 0 : pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
181 : : }
182 : : else
183 : : {
184 [ # # ]: 0 : for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
185 [ # # ]: 0 : for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
186 [ # # ][ # # ]: 0 : pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
187 : : }
188 : :
189 [ # # ]: 0 : ReleaseAccess( pWriteAcc );
190 : 0 : bRet = sal_True;
191 : : }
192 : : }
193 : : }
194 : : }
195 : :
196 : 1101 : return bRet;
197 : :
198 : : }
199 : :
200 : 7792 : sal_Bool AlphaMask::Erase( sal_uInt8 cTransparency )
201 : : {
202 [ + - ]: 7792 : return Bitmap::Erase( Color( cTransparency, cTransparency, cTransparency ) );
203 : : }
204 : :
205 : 0 : sal_Bool AlphaMask::Replace( const Bitmap& rMask, sal_uInt8 cReplaceTransparency )
206 : : {
207 : 0 : BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
208 : 0 : BitmapWriteAccess* pAcc = AcquireWriteAccess();
209 : 0 : sal_Bool bRet = sal_False;
210 : :
211 [ # # ][ # # ]: 0 : if( pMaskAcc && pAcc )
212 : : {
213 : 0 : const BitmapColor aReplace( cReplaceTransparency );
214 : 0 : const long nWidth = Min( pMaskAcc->Width(), pAcc->Width() );
215 : 0 : const long nHeight = Min( pMaskAcc->Height(), pAcc->Height() );
216 [ # # ]: 0 : const BitmapColor aMaskWhite( pMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
217 : :
218 [ # # ]: 0 : for( long nY = 0L; nY < nHeight; nY++ )
219 [ # # ]: 0 : for( long nX = 0L; nX < nWidth; nX++ )
220 [ # # ][ # # ]: 0 : if( pMaskAcc->GetPixel( nY, nX ) == aMaskWhite )
221 [ # # ]: 0 : pAcc->SetPixel( nY, nX, aReplace );
222 : : }
223 : :
224 : 0 : ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
225 : 0 : ReleaseAccess( pAcc );
226 : :
227 : 0 : return bRet;
228 : : }
229 : :
230 : 0 : sal_Bool AlphaMask::Replace( sal_uInt8 cSearchTransparency, sal_uInt8 cReplaceTransparency, sal_uLong
231 : : #ifdef DBG_UTIL
232 : : nTol
233 : : #endif
234 : : )
235 : : {
236 : 0 : BitmapWriteAccess* pAcc = AcquireWriteAccess();
237 : 0 : sal_Bool bRet = sal_False;
238 : :
239 : : DBG_ASSERT( !nTol, "AlphaMask::Replace: nTol not used yet" );
240 : :
241 [ # # ][ # # ]: 0 : if( pAcc && pAcc->GetBitCount() == 8 )
[ # # ]
242 : : {
243 : 0 : const long nWidth = pAcc->Width(), nHeight = pAcc->Height();
244 : :
245 [ # # ]: 0 : if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
246 : : {
247 [ # # ]: 0 : for( long nY = 0L; nY < nHeight; nY++ )
248 : : {
249 : 0 : Scanline pScan = pAcc->GetScanline( nY );
250 : :
251 [ # # ]: 0 : for( long nX = 0L; nX < nWidth; nX++, pScan++ )
252 : : {
253 [ # # ]: 0 : if( *pScan == cSearchTransparency )
254 : 0 : *pScan = cReplaceTransparency;
255 : : }
256 : : }
257 : : }
258 : : else
259 : : {
260 : 0 : BitmapColor aReplace( cReplaceTransparency );
261 : :
262 [ # # ]: 0 : for( long nY = 0L; nY < nHeight; nY++ )
263 : : {
264 [ # # ]: 0 : for( long nX = 0L; nX < nWidth; nX++ )
265 : : {
266 [ # # ][ # # ]: 0 : if( pAcc->GetPixel( nY, nX ).GetIndex() == cSearchTransparency )
267 [ # # ]: 0 : pAcc->SetPixel( nY, nX, aReplace );
268 : : }
269 : 0 : }
270 : : }
271 : :
272 : 0 : bRet = sal_True;
273 : : }
274 : :
275 [ # # ]: 0 : if( pAcc )
276 : 0 : ReleaseAccess( pAcc );
277 : :
278 : 0 : return bRet;
279 : : }
280 : :
281 : 210865 : void AlphaMask::ReleaseAccess( BitmapReadAccess* pAccess )
282 : : {
283 [ + - ]: 210865 : if( pAccess )
284 : : {
285 : 210865 : Bitmap::ReleaseAccess( pAccess );
286 : 210865 : Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
287 : : }
288 : 210865 : }
289 : :
290 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|