|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <fntstore.h> |
|
17 #include <bitmap.h> |
|
18 #include <bitstd.h> |
|
19 #include <bitdev.h> |
|
20 #include "BITPANIC.H" |
|
21 #include <bitdrawinterfaceid.h> |
|
22 #include <bmalphablend.h> |
|
23 #include <bitdraw.h> |
|
24 #include <graphics/fbsrasterizer.h> |
|
25 #include <graphics/bitmap.inl> |
|
26 #include <graphics/gdi/gdiinline.inl> |
|
27 |
|
28 /** |
|
29 Draws a bitmap. |
|
30 |
|
31 The function has 3 overloads. The first draws the bitmap given the top |
|
32 left hand corner, doing a compress/stretch based on its internally |
|
33 stored size in twips. The second does a compress/stretch to fit a |
|
34 given rectangle. The third takes a rectangular section of the source |
|
35 bitmap and does a compress/stretch to fit a given destination |
|
36 rectangle.The functions provide a concrete implementation of the pure |
|
37 virtual function <code>CGraphicsContext::DrawBitmap()</code>. The |
|
38 function behaviour is the same as documented in that class. |
|
39 */ |
|
40 EXPORT_C void CFbsBitGc::DrawBitmap(const TPoint& aPos,const CFbsBitmap* aSource) |
|
41 { |
|
42 if (aSource == NULL || !aSource->Handle()) |
|
43 return; |
|
44 |
|
45 aSource->BeginDataAccess(); |
|
46 const TSize bitmapTwips = aSource->SizeInTwips(); |
|
47 if (bitmapTwips.iWidth == 0 || bitmapTwips.iHeight == 0) |
|
48 { |
|
49 aSource->EndDataAccess(ETrue); |
|
50 return; |
|
51 } |
|
52 |
|
53 TSize scrpixels; |
|
54 scrpixels.iWidth = iDevice->HorizontalTwipsToPixels(bitmapTwips.iWidth); |
|
55 scrpixels.iHeight = iDevice->VerticalTwipsToPixels(bitmapTwips.iHeight); |
|
56 |
|
57 DrawBitmap(TRect(aPos, scrpixels), aSource, TRect(aSource->SizeInPixels())); |
|
58 aSource->EndDataAccess(ETrue); |
|
59 } |
|
60 |
|
61 EXPORT_C void CFbsBitGc::DrawBitmap(const TRect& aDestRect,const CFbsBitmap* aSource) |
|
62 { |
|
63 if (aSource == NULL || !aSource->Handle()) |
|
64 return; |
|
65 |
|
66 aSource->BeginDataAccess(); |
|
67 DrawBitmap(aDestRect, aSource, TRect(aSource->SizeInPixels())); |
|
68 aSource->EndDataAccess(ETrue); |
|
69 } |
|
70 |
|
71 EXPORT_C void CFbsBitGc::DrawBitmap(const TRect& aDestRect, |
|
72 const CFbsBitmap* aSource, |
|
73 const TRect& aSourceRect) |
|
74 { |
|
75 if (CheckDevice(aDestRect) || aSourceRect.IsEmpty() || aSource == NULL || !aSource->Handle()) |
|
76 return; |
|
77 |
|
78 aSource->BeginDataAccess(); |
|
79 //aSourceRect should be in the bounds of the bitmap |
|
80 TSize bitmapSize(aSource->SizeInPixels()); |
|
81 if ( aSourceRect.iTl.iX < 0 |
|
82 || aSourceRect.iTl.iY < 0 |
|
83 || aSourceRect.iBr.iX > bitmapSize.iWidth |
|
84 || aSourceRect.iBr.iY > bitmapSize.iHeight) |
|
85 { |
|
86 aSource->EndDataAccess(ETrue); |
|
87 return; |
|
88 } |
|
89 |
|
90 TRect destRect(aDestRect); |
|
91 destRect.Move(iOrigin); |
|
92 AddRect(destRect); |
|
93 |
|
94 TRect clippedDestRect(destRect); |
|
95 if (UserClipRect(clippedDestRect)) |
|
96 { |
|
97 aSource->EndDataAccess(ETrue); |
|
98 return; |
|
99 } |
|
100 |
|
101 CFbsBitGcBitmap* srce = (CFbsBitGcBitmap*)aSource; |
|
102 SetupDevice(); |
|
103 iDevice->DrawingBegin(); |
|
104 |
|
105 CBitwiseBitmap* bmp = srce->Address(); |
|
106 BG_ASSERT_DEBUG(bmp,EBitgdiPanicInvalidBitmap); |
|
107 |
|
108 CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aSource, destRect, aSourceRect); |
|
109 |
|
110 const TPoint ditherOrigin(iDitherOrigin + aDestRect.iTl); |
|
111 |
|
112 const TInt limit = iDefaultRegionPtr->Count(); |
|
113 CGraphicsAccelerator* ga = GraphicsAccelerator(); |
|
114 if (ga && iShadowMode==CFbsDrawDevice::ENoShadow && iDrawMode==EDrawModePEN) |
|
115 { |
|
116 TInt gaOperationResult = KErrUnknown; |
|
117 TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aSource)); |
|
118 iDevice->DrawingEnd(); |
|
119 |
|
120 if (destRect.Size() == aSourceRect.Size()) |
|
121 { |
|
122 const TPoint offset(aSourceRect.iTl - destRect.iTl); |
|
123 for(TInt count=0;count<limit;count++) |
|
124 { |
|
125 iClipRect=(*iDefaultRegionPtr)[count]; |
|
126 if(!iClipRect.Intersects(clippedDestRect)) |
|
127 continue; |
|
128 iClipRect.Intersection(clippedDestRect); |
|
129 |
|
130 TRect clippedSrceRect(iClipRect); |
|
131 clippedSrceRect.Move(offset); |
|
132 gaOperationResult = ga->Operation(TGopBitBlt(iClipRect.iTl,bitmapSpec,clippedSrceRect)); |
|
133 if (gaOperationResult!=KErrNone) |
|
134 break; |
|
135 } |
|
136 iDevice->iDrawDevice->UpdateRegion(iClipRect); |
|
137 } |
|
138 else |
|
139 { |
|
140 RRegion clippedRegion; |
|
141 for(TInt clipIt=0;clipIt<limit;clipIt++) |
|
142 { |
|
143 TRect clipRect((*iDefaultRegionPtr)[clipIt]); |
|
144 clipRect.Intersection(clippedDestRect); |
|
145 if (!clipRect.IsEmpty()) |
|
146 clippedRegion.AddRect(clipRect); |
|
147 } |
|
148 TRect srcCopy(aSourceRect); // Needed because TGopScaledBitBlt takes a non-const value |
|
149 // const_cast needed because Operation takes a non-const region ptr :( |
|
150 gaOperationResult = ga->Operation(TGopScaledBitBlt(destRect,bitmapSpec,srcCopy),clippedRegion.Count(),const_cast<TRect*>(clippedRegion.RectangleList())); |
|
151 if (gaOperationResult==KErrNone) |
|
152 iDevice->iDrawDevice->Update(clippedRegion); |
|
153 clippedRegion.Close(); |
|
154 } |
|
155 if(gaOperationResult == KErrNone) |
|
156 goto finish; |
|
157 iDevice->DrawingBegin(); |
|
158 |
|
159 } |
|
160 // |
|
161 { // to stop error from gccxml build about previous jump to finish skipping initialisation of opaqueSource |
|
162 const TBool opaqueSource = (!IsAlphaChannel(aSource->DisplayMode())) && (iDrawMode == EDrawModePEN); |
|
163 if (opaqueSource) |
|
164 { |
|
165 iDrawMode = EDrawModeWriteAlpha; |
|
166 } |
|
167 |
|
168 for (TInt count = 0; count < limit; count++) |
|
169 { |
|
170 iClipRect = (*iDefaultRegionPtr)[count]; |
|
171 if (!iClipRect.Intersects(clippedDestRect)) |
|
172 continue; |
|
173 |
|
174 iClipRect.Intersection(clippedDestRect); |
|
175 DoDrawBitmap(destRect,bmp,aSource->DataAddress(),aSource->DataStride(),aSourceRect,ditherOrigin); |
|
176 |
|
177 iDevice->iDrawDevice->UpdateRegion(iClipRect); |
|
178 } |
|
179 if (opaqueSource) |
|
180 { |
|
181 iDrawMode = EDrawModePEN; |
|
182 } |
|
183 |
|
184 } |
|
185 iDevice->DrawingEnd(); |
|
186 |
|
187 finish: |
|
188 if (rasterizer) |
|
189 { |
|
190 rasterizer->EndBitmap(aSource->SerialNumber()); |
|
191 } |
|
192 aSource->EndDataAccess(ETrue); |
|
193 } |
|
194 |
|
195 |
|
196 void CFbsBitGc::DoDrawBitmap(const TRect& aDestRect, |
|
197 CBitwiseBitmap* aBitmap, |
|
198 TUint32* aBase, |
|
199 TInt aStride, |
|
200 const TRect& aSrceRect, |
|
201 const TPoint& aDitherOrigin) |
|
202 { |
|
203 CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; |
|
204 #ifdef _DEBUG |
|
205 TRect deviceDestRect; |
|
206 drawDevice->GetDrawRect(deviceDestRect); |
|
207 #endif |
|
208 BG_ASSERT_DEBUG(iClipRect.iTl.iX >= deviceDestRect.iTl.iX, EBitgdiPanicOutOfBounds); |
|
209 BG_ASSERT_DEBUG(iClipRect.iTl.iY >= deviceDestRect.iTl.iY, EBitgdiPanicOutOfBounds); |
|
210 BG_ASSERT_DEBUG(iClipRect.iBr.iX <= deviceDestRect.iBr.iX, EBitgdiPanicOutOfBounds); |
|
211 BG_ASSERT_DEBUG(iClipRect.iBr.iY <= deviceDestRect.iBr.iY, EBitgdiPanicOutOfBounds); |
|
212 |
|
213 if (aDestRect.Size() == aSrceRect.Size()) |
|
214 { |
|
215 TRect clippedRect(aDestRect); |
|
216 clippedRect.Intersection(iClipRect); |
|
217 |
|
218 if (!clippedRect.IsEmpty()) |
|
219 { |
|
220 const TPoint destPoint(clippedRect.iTl); |
|
221 clippedRect.Move(aSrceRect.iTl - aDestRect.iTl); |
|
222 DoBitBlt(destPoint,aBitmap,aBase,aStride,clippedRect); |
|
223 } |
|
224 |
|
225 return; |
|
226 } |
|
227 MFastBlend* fastBlend=NULL; |
|
228 if (FastBlendInterface(aBitmap,NULL,fastBlend)==KErrNone) |
|
229 { |
|
230 if (fastBlend->FastBlendBitmapScaled(iClipRect, aDestRect, aSrceRect, aBase, aStride, aBitmap->DisplayMode(), aBitmap->SizeInPixels(), iDrawMode, iShadowMode)== KErrNone) |
|
231 { |
|
232 return; |
|
233 } |
|
234 } |
|
235 |
|
236 TUint32* scanLineBuffer = drawDevice->ScanLineBuffer(); |
|
237 const TInt scanLineBytes = drawDevice->ScanLineBytes(); |
|
238 TPtr8 scanLineDes(REINTERPRET_CAST(TUint8*,scanLineBuffer),scanLineBytes,scanLineBytes); |
|
239 |
|
240 // For EColor16MU targets, don't use EColor16MAP when draw mode is EDrawModeWriteAlpha. |
|
241 // Format conversion provides no performance gain and WriteLine expects EColor16MU |
|
242 // in this case. |
|
243 const TDisplayMode dispMode = drawDevice->DisplayMode() == EColor16MU && iDrawMode == EDrawModeWriteAlpha ? EColor16MU : drawDevice->ScanLineDisplayMode(); |
|
244 |
|
245 TLinearDDA xLine; |
|
246 TInt bitmapXStart = 0; |
|
247 xLine.Construct(TPoint(aSrceRect.iTl.iX,aDestRect.iTl.iX), |
|
248 TPoint(aSrceRect.iBr.iX,aDestRect.iBr.iX),TLinearDDA::ELeft); |
|
249 xLine.JumpToYCoord(bitmapXStart,iClipRect.iTl.iX); |
|
250 |
|
251 TLinearDDA yLine; |
|
252 TPoint yCoord(aSrceRect.iTl.iY,aDestRect.iTl.iY); |
|
253 yLine.Construct(yCoord,TPoint(aSrceRect.iBr.iY,aDestRect.iBr.iY),TLinearDDA::ELeft); |
|
254 TInt dummy; |
|
255 yLine.JumpToYCoord2(dummy,iClipRect.iTl.iY); |
|
256 yCoord.SetXY(dummy,iClipRect.iTl.iY); |
|
257 |
|
258 TBool finished = EFalse; |
|
259 TPoint ditherOrigin(aDitherOrigin + iClipRect.iTl); |
|
260 const TInt srceWidth = aSrceRect.Width(); |
|
261 const TInt destWidth = aDestRect.Width(); |
|
262 const TInt clipWidth = iClipRect.Width(); |
|
263 const TInt clipStrch = iClipRect.iTl.iX - aDestRect.iTl.iX; |
|
264 |
|
265 TLineScanningPosition lineScanPos(aBase); |
|
266 while (yCoord.iY < iClipRect.iBr.iY && !finished) |
|
267 { |
|
268 aBitmap->StretchScanLine(scanLineDes,TPoint(bitmapXStart,yCoord.iX), |
|
269 clipStrch,clipWidth,destWidth,aSrceRect.iTl.iX, |
|
270 srceWidth,ditherOrigin,dispMode,aBase,lineScanPos); |
|
271 if (yCoord.iY==iClipRect.iTl.iY) |
|
272 aBitmap->SetCompressionBookmark(lineScanPos, aBase,NULL); |
|
273 drawDevice->WriteLine(iClipRect.iTl.iX,yCoord.iY,clipWidth, scanLineBuffer,iDrawMode); |
|
274 finished = yLine.NextStep(yCoord); |
|
275 ditherOrigin.iY++; |
|
276 } |
|
277 } |
|
278 |
|
279 /** The method draws a specified rectangle from a bitmap and |
|
280 its mask into another rectangle and does a compress/stretch |
|
281 to fit a given destination rectangle. |
|
282 |
|
283 @note When using this function with a 256 Mask bitmap, it blends. |
|
284 Otherwise (e.g. with a 4bpp mask), this function masks rather than blends. |
|
285 If a user wants to blend the source into the destination they should use |
|
286 CFbsBitGc::AlphaBlendBitmaps() instead. |
|
287 |
|
288 @publishedAll |
|
289 @released |
|
290 |
|
291 @param aDestRect The rectangle within which the masked bitmap is to be drawn. |
|
292 @param aBitmap A pointer to the source bitmap. |
|
293 @param aSourceRect The rectangle in the source bitmap that is copied to the |
|
294 destination rectangle. |
|
295 @param aMaskBitmap A pointer to the mask bitmap. |
|
296 @param aInvertMask If false, a source pixel that is masked by a black pixel |
|
297 is not transferred to the destination rectangle. If true, then a source pixel |
|
298 that is masked by a white pixel is not transferred to the destination rectangle. |
|
299 |
|
300 @pre aBitmap != NULL |
|
301 @pre aBitmap->Handle() != 0 |
|
302 @pre aMaskBitmap != NULL |
|
303 @pre aMaskBitmap->Handle() != 0 |
|
304 @pre !aSourceRect.IsEmpty() |
|
305 @pre aSourceRect should be in the bounds of the bitmap |
|
306 */ |
|
307 EXPORT_C void CFbsBitGc::DrawBitmapMasked(const TRect& aDestRect, |
|
308 const CFbsBitmap* aBitmap, |
|
309 const TRect& aSourceRect, |
|
310 const CFbsBitmap* aMaskBitmap, |
|
311 TBool aInvertMask) |
|
312 { |
|
313 if (aBitmap == NULL || !aBitmap->Handle() || aMaskBitmap == NULL || |
|
314 !aMaskBitmap->Handle() || aSourceRect.IsEmpty() || CheckDevice(aDestRect)) |
|
315 { |
|
316 return; |
|
317 } |
|
318 |
|
319 aBitmap->BeginDataAccess(); |
|
320 aMaskBitmap->BeginDataAccess(); |
|
321 |
|
322 //aSourceRect should be in the bounds of the bitmap |
|
323 TSize bitmapSize(aBitmap->SizeInPixels()); |
|
324 if ( aSourceRect.iTl.iX < 0 |
|
325 || aSourceRect.iTl.iY < 0 |
|
326 || aSourceRect.iBr.iX > bitmapSize.iWidth |
|
327 || aSourceRect.iBr.iY > bitmapSize.iHeight) |
|
328 { |
|
329 aBitmap->EndDataAccess(ETrue); |
|
330 aMaskBitmap->EndDataAccess(ETrue); |
|
331 return; |
|
332 } |
|
333 |
|
334 TRect destRect(aDestRect); |
|
335 destRect.Move(iOrigin); |
|
336 AddRect(destRect); |
|
337 TRect clippedDestRect(destRect); |
|
338 if (UserClipRect(clippedDestRect)) |
|
339 { |
|
340 aBitmap->EndDataAccess(ETrue); |
|
341 aMaskBitmap->EndDataAccess(ETrue); |
|
342 return; |
|
343 } |
|
344 |
|
345 SetupDevice(); |
|
346 const TBool opaqueSource = (!IsAlphaChannel(aBitmap->DisplayMode())) && (iDrawMode == EDrawModePEN); |
|
347 iDevice->DrawingBegin(); |
|
348 |
|
349 CBitwiseBitmap* srcebmp = ((CFbsBitGcBitmap*)aBitmap)->Address(); |
|
350 CBitwiseBitmap* maskbmp = ((CFbsBitGcBitmap*)aMaskBitmap)->Address(); |
|
351 BG_ASSERT_DEBUG(srcebmp,EBitgdiPanicInvalidBitmap); |
|
352 BG_ASSERT_DEBUG(maskbmp,EBitgdiPanicInvalidBitmap); |
|
353 |
|
354 CFbsRasterizer* rasterizer = PrepareRasterizerForExtendedBitmap(*aBitmap, destRect, aSourceRect); |
|
355 CFbsRasterizer* maskRasterizer = NULL; |
|
356 if (srcebmp != maskbmp) |
|
357 { |
|
358 if (aMaskBitmap->SizeInPixels().iWidth >= aBitmap->SizeInPixels().iWidth |
|
359 && aMaskBitmap->SizeInPixels().iHeight >= aBitmap->SizeInPixels().iHeight) |
|
360 { |
|
361 // Mask is not tiled. Pass same region of interest as source bitmap to rasterizer. |
|
362 maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap, destRect, aSourceRect); |
|
363 } |
|
364 else |
|
365 { |
|
366 // Mask is tiled. Do not pass any region of interest to rasterizer. |
|
367 maskRasterizer = PrepareRasterizerForExtendedBitmap(*aMaskBitmap); |
|
368 } |
|
369 } |
|
370 |
|
371 const TPoint ditherOrigin(iDitherOrigin + aDestRect.iTl); |
|
372 const TInt limit = iDefaultRegionPtr->Count(); |
|
373 // |
|
374 CGraphicsAccelerator* ga = GraphicsAccelerator(); |
|
375 if (ga && iShadowMode==CFbsDrawDevice::ENoShadow && (aMaskBitmap->DisplayMode()!=EGray2 || !aInvertMask) && iDrawMode==EDrawModePEN) |
|
376 { |
|
377 TInt gaOperationResult = KErrUnknown; |
|
378 TAcceleratedBitmapSpec bitmapSpec(const_cast<CFbsBitmap*>(aBitmap)); |
|
379 iDevice->DrawingEnd(); |
|
380 TAcceleratedBitmapSpec maskSpec(const_cast<CFbsBitmap*>(aMaskBitmap)); |
|
381 const TPoint offset(aSourceRect.iTl - destRect.iTl); |
|
382 |
|
383 if (destRect.Size() == aSourceRect.Size()) |
|
384 { |
|
385 for(TInt count=0;count<limit;count++) |
|
386 { |
|
387 iClipRect=(*iDefaultRegionPtr)[count]; |
|
388 if(!iClipRect.Intersects(clippedDestRect)) |
|
389 continue; |
|
390 iClipRect.Intersection(clippedDestRect); |
|
391 |
|
392 TRect clippedSrceRect(iClipRect); |
|
393 clippedSrceRect.Move(offset); |
|
394 |
|
395 gaOperationResult = ga->Operation(TGopBitBltMasked(iClipRect.iTl,bitmapSpec,clippedSrceRect,maskSpec)); |
|
396 if (gaOperationResult!=KErrNone) |
|
397 break; |
|
398 iDevice->iDrawDevice->UpdateRegion(iClipRect); |
|
399 } |
|
400 } |
|
401 else |
|
402 { |
|
403 RRegion clippedRegion; |
|
404 for(TInt clipIt=0;clipIt<limit;clipIt++) |
|
405 { |
|
406 TRect clipRect((*iDefaultRegionPtr)[clipIt]); |
|
407 clipRect.Intersection(clippedDestRect); |
|
408 if (!clipRect.IsEmpty()) |
|
409 clippedRegion.AddRect(clipRect); |
|
410 } |
|
411 TRect srcCopy(aSourceRect); // Needed because TGopScaledBitBltMasked takes a non-const value |
|
412 // const_cast needed because Operation takes a non-const region ptr :( |
|
413 gaOperationResult = ga->Operation(TGopScaledBitBltMasked(destRect,bitmapSpec,srcCopy,maskSpec),clippedRegion.Count(),const_cast<TRect*>(clippedRegion.RectangleList())); |
|
414 if (gaOperationResult==KErrNone) |
|
415 iDevice->iDrawDevice->Update(clippedRegion); |
|
416 clippedRegion.Close(); |
|
417 } |
|
418 if (gaOperationResult==KErrNone) |
|
419 goto finish; |
|
420 iDevice->DrawingBegin(); |
|
421 } |
|
422 // |
|
423 if (opaqueSource) |
|
424 iDrawMode = EDrawModeWriteAlpha; |
|
425 for (TInt count = 0; count < limit; count++) |
|
426 { |
|
427 iClipRect = (*iDefaultRegionPtr)[count]; |
|
428 if (!iClipRect.Intersects(clippedDestRect)) |
|
429 continue; |
|
430 iClipRect.Intersection(clippedDestRect); |
|
431 DoDrawBitmapMasked(destRect, |
|
432 srcebmp, |
|
433 aBitmap->DataAddress(), |
|
434 aSourceRect, |
|
435 maskbmp, |
|
436 aMaskBitmap->DataAddress(), |
|
437 aInvertMask, ditherOrigin); |
|
438 iDevice->iDrawDevice->UpdateRegion(iClipRect); |
|
439 } |
|
440 if (opaqueSource) |
|
441 iDrawMode = EDrawModePEN; |
|
442 iDevice->DrawingEnd(); |
|
443 finish: |
|
444 if (rasterizer) |
|
445 { |
|
446 rasterizer->EndBitmap(aBitmap->SerialNumber()); |
|
447 } |
|
448 if (maskRasterizer) |
|
449 { |
|
450 maskRasterizer->EndBitmap(aMaskBitmap->SerialNumber()); |
|
451 } |
|
452 aBitmap->EndDataAccess(ETrue); |
|
453 aMaskBitmap->EndDataAccess(ETrue); |
|
454 } |
|
455 |
|
456 /** The method draws a specified rectangle from a bitmap and |
|
457 its mask into another rectangle and does a compress/stretch |
|
458 to fit a given destination rectangle. |
|
459 |
|
460 This is an overload, which takes CWsBitmap* as argument, which |
|
461 in turn calls the other overload. |
|
462 |
|
463 Note: A pointer to CWsBitmap must have the same pointer value as a pointer |
|
464 to the associated CFbsBitmap, otherwise code in BitGdi component will be |
|
465 Broken. |
|
466 |
|
467 @note When using this function with a 256 Mask bitmap, it blends. |
|
468 Otherwise (e.g. with a 4bpp mask), this function masks rather than blends. |
|
469 If a user wants to blend the source into the destination they should use |
|
470 CFbsBitGc::AlphaBlendBitmaps() instead. |
|
471 |
|
472 @publishedAll |
|
473 @released |
|
474 |
|
475 @param aDestRect The rectangle within which the masked bitmap is to be drawn. |
|
476 @param aBitmap A pointer to the source bitmap. |
|
477 @param aSourceRect The rectangle in the source bitmap that is copied to the |
|
478 destination rectangle. |
|
479 @param aMaskBitmap A pointer to the mask bitmap. |
|
480 @param aInvertMask If false, a source pixel that is masked by a black pixel |
|
481 is not transferred to the destination rectangle. If true, then a source pixel |
|
482 that is masked by a white pixel is not transferred to the destination rectangle. |
|
483 |
|
484 @pre aBitmap != NULL |
|
485 @pre aBitmap->Handle() != 0 |
|
486 @pre aMaskBitmap != NULL |
|
487 @pre aMaskBitmap->Handle() != 0 |
|
488 @pre !aSourceRect.IsEmpty() |
|
489 */ |
|
490 EXPORT_C void CFbsBitGc::DrawBitmapMasked(const TRect& aDestRect, |
|
491 const CWsBitmap* aBitmap, |
|
492 const TRect& aSourceRect, |
|
493 const CWsBitmap* aMaskBitmap, |
|
494 TBool aInvertMask) |
|
495 { |
|
496 DrawBitmapMasked(aDestRect,REINTERPRET_CAST(const CFbsBitmap*,aBitmap),aSourceRect,REINTERPRET_CAST(const CFbsBitmap*,aMaskBitmap),aInvertMask); |
|
497 } |