|
1 /* |
|
2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Render context implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include <eikenv.h> // CCoeEnv |
|
20 |
|
21 #include "CMIDGraphics.h" |
|
22 #include "CM2GRenderContext.h" |
|
23 #include "MM2GSVGProxy.h" |
|
24 |
|
25 M2G_NS_START |
|
26 |
|
27 // EXTERNAL DATA STRUCTURES |
|
28 |
|
29 // EXTERNAL FUNCTION PROTOTYPES |
|
30 |
|
31 // CONSTANTS |
|
32 /* static */ const TReal32 MM2GRenderContext::KFullOpaque = 1.0; |
|
33 /* static */ |
|
34 const TReal32 MM2GRenderContext::KFullTransparency = 0.0; |
|
35 /* static */ |
|
36 const TUint8 MM2GRenderContext::KMaxAlphaValue = 255; |
|
37 /* static */ |
|
38 const TDisplayMode MM2GRenderContext::KDefaultDisplayMode = EColor16MA; |
|
39 /* static */ |
|
40 const TDisplayMode MM2GRenderContext::KMaskDisplayMode = EGray256; |
|
41 |
|
42 // MACROS |
|
43 |
|
44 // LOCAL CONSTANTS AND MACROS |
|
45 |
|
46 // MODULE DATA STRUCTURES |
|
47 |
|
48 // LOCAL FUNCTION PROTOTYPES |
|
49 |
|
50 // FORWARD DECLARATIONS |
|
51 |
|
52 // ----------------------------------------------------------------------------- |
|
53 // CM2GRenderContext::CM2GRenderContext |
|
54 // ----------------------------------------------------------------------------- |
|
55 CM2GRenderContext::CM2GRenderContext() |
|
56 : CBase(), |
|
57 iProxy(NULL), |
|
58 iEngineHandle(M2G_INVALID_HANDLE), |
|
59 iAlpha(MM2GRenderContext::KFullOpaque), |
|
60 iScaledAlpha(MM2GRenderContext::KMaxAlphaValue), |
|
61 iMaskBmp(NULL), |
|
62 iTargetBmp(NULL), |
|
63 iImgBmp(NULL) |
|
64 { |
|
65 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::CM2GRenderContext"); |
|
66 } |
|
67 |
|
68 // ----------------------------------------------------------------------------- |
|
69 // CM2GRenderContext::NewL |
|
70 // ----------------------------------------------------------------------------- |
|
71 CM2GRenderContext* CM2GRenderContext::NewL(MM2GSVGProxy* aProxy) |
|
72 { |
|
73 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::NewL()"); |
|
74 |
|
75 CM2GRenderContext* self = new(ELeave) CM2GRenderContext; |
|
76 CleanupStack::PushL(self); |
|
77 |
|
78 self->ConstructL(aProxy); |
|
79 |
|
80 CleanupStack::Pop(); |
|
81 |
|
82 return self; |
|
83 } |
|
84 |
|
85 // ----------------------------------------------------------------------------- |
|
86 // CM2GRenderContext::~CM2GRenderContext |
|
87 // ----------------------------------------------------------------------------- |
|
88 CM2GRenderContext::~CM2GRenderContext() |
|
89 { |
|
90 M2G_DEBUG_2("M2G_DEBUG: CM2GRenderContext::~CM2GRenderContext() - proxy=%d, engine=%d", iProxy, iEngineHandle); |
|
91 if ((iEngineHandle != M2G_INVALID_HANDLE) && (iProxy != NULL)) |
|
92 { |
|
93 TRAP_IGNORE(iProxy->DeleteSvgEngineL(iEngineHandle)); |
|
94 } |
|
95 delete iImgBmp; |
|
96 delete iMaskBmp; |
|
97 iFbsSession.Disconnect(); |
|
98 } |
|
99 |
|
100 // ----------------------------------------------------------------------------- |
|
101 // CM2GRenderContext::BindL |
|
102 // ----------------------------------------------------------------------------- |
|
103 void CM2GRenderContext::BindL(TInt& aTargetHandle, TBool aUiToolKit) |
|
104 { |
|
105 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::BindL()"); |
|
106 if (!aUiToolKit) |
|
107 { |
|
108 // Current Ui Toolkit is LCDUI |
|
109 // Set target graphics bitmap |
|
110 CMIDGraphics* graphics = MIDUnhand<CMIDGraphics>(aTargetHandle); |
|
111 iTargetBmp = graphics->Bitmap(); |
|
112 User::LeaveIfNull(iTargetBmp); |
|
113 #ifdef RD_JAVA_NGA_ENABLED |
|
114 iTargetCanvas = graphics->GetTargetCanvas(); |
|
115 #endif // RD_JAVA_NGA_ENABLED |
|
116 } |
|
117 // initialize the svg image bitmap (on which we will render later during RenderL()) |
|
118 InitImageBitmapL(); |
|
119 } |
|
120 |
|
121 // ----------------------------------------------------------------------------- |
|
122 // CM2GRenderContext::GetImgHandleL |
|
123 // ----------------------------------------------------------------------------- |
|
124 TM2GBitmapHandle CM2GRenderContext::GetImgHandleL() const |
|
125 { |
|
126 User::LeaveIfNull(iImgBmp); |
|
127 |
|
128 return REINTERPRET_CAST(TM2GBitmapHandle, iImgBmp); |
|
129 } |
|
130 // ----------------------------------------------------------------------------- |
|
131 // CM2GRenderContext::InitImageBitmapL |
|
132 // ----------------------------------------------------------------------------- |
|
133 void CM2GRenderContext::InitImageBitmapL() |
|
134 { |
|
135 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::InitImageBitmapL() - begin"); |
|
136 |
|
137 // get the screen size |
|
138 TSize screenSize = CEikonEnv::Static()->ScreenDevice()->SizeInPixels(); |
|
139 |
|
140 if (iImgBmp == NULL || (iImgBmp && iImgBmp->SizeInPixels() != screenSize)) |
|
141 { |
|
142 M2G_DEBUG_2("M2G_DEBUG: CM2GRenderContext::InitImageBitmapL() - new bitmap: w=%d, h=%d", screenSize.iWidth, screenSize.iHeight); |
|
143 // Create a new svg surface if first time |
|
144 // or the size of the screen is different than the actual buffer size |
|
145 |
|
146 delete iImgBmp; |
|
147 iImgBmp = NULL; |
|
148 |
|
149 iImgBmp = new(ELeave) CFbsBitmap(); |
|
150 |
|
151 User::LeaveIfError( |
|
152 iImgBmp->Create(screenSize, KDefaultDisplayMode)); |
|
153 } |
|
154 |
|
155 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::InitImageBitmapL() - end"); |
|
156 } |
|
157 |
|
158 // ----------------------------------------------------------------------------- |
|
159 // CM2GRenderContext::InitMaskL |
|
160 // ----------------------------------------------------------------------------- |
|
161 void CM2GRenderContext::InitMaskL(TSize aSize) |
|
162 { |
|
163 M2G_DEBUG_2("M2G_DEBUG: CM2GRenderContext::InitMaskL( w=%d, h=%d ) - begin", aSize.iWidth, aSize.iHeight); |
|
164 |
|
165 if (iMaskBmp == NULL || (iMaskBmp && iMaskBmp->SizeInPixels() != aSize)) |
|
166 { |
|
167 // Create a new mask but first delete the previous one if allocated |
|
168 delete iMaskBmp; |
|
169 iMaskBmp = NULL; |
|
170 |
|
171 M2G_DEBUG_0(" M2G_DEBUG: >CM2GRenderContext::InitMaskL() creates new mask "); |
|
172 |
|
173 iMaskBmp = new(ELeave) CFbsBitmap(); |
|
174 |
|
175 User::LeaveIfError( |
|
176 iMaskBmp->Create(aSize, KMaskDisplayMode)); |
|
177 } |
|
178 |
|
179 User::LeaveIfNull(iMaskBmp); |
|
180 |
|
181 // Mask is filled with the current alpha factor |
|
182 FillBitmapL(iMaskBmp, iScaledAlpha); |
|
183 |
|
184 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::InitMaskL() - end"); |
|
185 } |
|
186 |
|
187 // ----------------------------------------------------------------------------- |
|
188 // CM2GRenderContext::ReleaseL |
|
189 // ----------------------------------------------------------------------------- |
|
190 void CM2GRenderContext::ReleaseL() |
|
191 { |
|
192 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::ReleaseL() - begin"); |
|
193 iTargetBmp = NULL; |
|
194 #ifdef RD_JAVA_NGA_ENABLED |
|
195 iTargetCanvas = NULL; |
|
196 #endif // RD_JAVA_NGA_ENABLED |
|
197 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::ReleaseL() - end"); |
|
198 } |
|
199 |
|
200 // ----------------------------------------------------------------------------- |
|
201 // CM2GRenderContext::RenderL |
|
202 // ----------------------------------------------------------------------------- |
|
203 void CM2GRenderContext::RenderLCDUIL( |
|
204 TM2GSvgDocumentHandle& aSvgDocHandle, |
|
205 const TReal32 aCurrentTime, |
|
206 TInt aSvgW, TInt aSvgH, |
|
207 TM2GRenderRect& aRect |
|
208 ) |
|
209 { |
|
210 // prepare viewbox |
|
211 TRect viewbox; |
|
212 TPoint anchor; |
|
213 |
|
214 PrepareViewbox(aRect, aSvgW, aSvgH, viewbox, anchor); |
|
215 |
|
216 RenderLCDUIL(aSvgDocHandle, aCurrentTime, viewbox, anchor); |
|
217 #ifdef RD_JAVA_NGA_ENABLED |
|
218 if (iTargetCanvas && iTargetCanvas->IsEglAvailable()) |
|
219 { |
|
220 iTargetCanvas->UpdateRect(TRect(anchor, viewbox.Size())); |
|
221 } |
|
222 #endif // RD_JAVA_NGA_ENABLED |
|
223 |
|
224 } |
|
225 |
|
226 // ----------------------------------------------------------------------------- |
|
227 void CM2GRenderContext::RenderESWTL( |
|
228 TM2GSvgDocumentHandle& aSvgDocHandle, |
|
229 const TReal32 aCurrentTime, |
|
230 TInt aSvgW, TInt aSvgH, |
|
231 TM2GRenderRect& aRect, |
|
232 MSwtClient* aClientHandle, |
|
233 TBool aUseNativeClear, |
|
234 TInt* aReturnData) |
|
235 { |
|
236 // prepare viewbox |
|
237 TRect viewbox; |
|
238 TPoint anchor; |
|
239 |
|
240 PrepareViewbox(aRect, aSvgW, aSvgH, viewbox, anchor); |
|
241 |
|
242 aReturnData[0] = 0; |
|
243 aReturnData[1] = 0; |
|
244 aReturnData[2] = 0; |
|
245 aReturnData[3] = 0; |
|
246 aReturnData[4] = anchor.iX; |
|
247 aReturnData[5] = anchor.iY; |
|
248 aReturnData[6] = viewbox.iTl.iX; |
|
249 aReturnData[7] = viewbox.iTl.iY; |
|
250 aReturnData[8] = viewbox.Width(); |
|
251 aReturnData[9] = viewbox.Height(); |
|
252 |
|
253 RenderESWTL(aSvgDocHandle, aCurrentTime, viewbox, anchor, aClientHandle, aUseNativeClear, aReturnData); |
|
254 |
|
255 return; |
|
256 } |
|
257 // CM2GRenderContext::SetRenderingQualityL |
|
258 // ----------------------------------------------------------------------------- |
|
259 void CM2GRenderContext::SetRenderingQualityL(TInt aMode) |
|
260 { |
|
261 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::SetRenderingQualityL()"); |
|
262 User::LeaveIfNull(iProxy); |
|
263 iProxy->RenderQualityL(iEngineHandle, aMode); |
|
264 } |
|
265 |
|
266 // ----------------------------------------------------------------------------- |
|
267 // CM2GRenderContext::SetTransparencyL |
|
268 // ----------------------------------------------------------------------------- |
|
269 void CM2GRenderContext::SetTransparency(TReal32 aAlpha) |
|
270 { |
|
271 iAlpha = aAlpha; |
|
272 iScaledAlpha = STATIC_CAST(TUint8, (aAlpha * MM2GRenderContext::KMaxAlphaValue)); |
|
273 } |
|
274 |
|
275 // ----------------------------------------------------------------------------- |
|
276 // CM2GRenderContext::ConstructL |
|
277 // ----------------------------------------------------------------------------- |
|
278 void CM2GRenderContext::ConstructL(MM2GSVGProxy* aProxy) |
|
279 { |
|
280 // Init member variables |
|
281 SetTransparency(MM2GRenderContext::KFullOpaque); |
|
282 |
|
283 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::ConstructL() - begin"); |
|
284 |
|
285 if (aProxy) |
|
286 { |
|
287 iProxy = aProxy; |
|
288 iProxy->CreateSvgEngineL(iEngineHandle); |
|
289 M2G_DEBUG_2("M2G_DEBUG: CM2GRenderContext::ConstructL() - proxy: %d, new engine: %d", iProxy, iEngineHandle); |
|
290 } |
|
291 else |
|
292 { |
|
293 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::ConstructL() - proxy is invalid"); |
|
294 M2G_THROW(KM2GArgNotOk); |
|
295 } |
|
296 |
|
297 User::LeaveIfError(iFbsSession.Connect()); |
|
298 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::ConstructL() - end"); |
|
299 } |
|
300 // ----------------------------------------------------------------------------- |
|
301 // CM2GRenderContext::PrepareViewbox |
|
302 // ----------------------------------------------------------------------------- |
|
303 void CM2GRenderContext::PrepareViewbox( |
|
304 TM2GRenderRect& aRr, |
|
305 TInt aSvgW, TInt aSvgH, |
|
306 TRect& aViewbox, TPoint& aAnchor) |
|
307 { |
|
308 M2G_DEBUG_6("M2G_DEBUG: CM2GRenderContext::PrepareViewbox() cX=%d, cY=%d, cW=%d, cH=%d, anchorX=%d, anchorY=%d - begin", aRr.GetClipX(), aRr.GetClipY(), aRr.GetClipW(), aRr.GetClipH(), aRr.GetAnchorX(), aRr.GetAnchorY()); |
|
309 |
|
310 // Create an anchor point and an svg render area rect |
|
311 aAnchor.SetXY(aRr.GetAnchorX(), aRr.GetAnchorY()); |
|
312 aViewbox.SetRect(aAnchor, TSize(aSvgW, aSvgH)); |
|
313 |
|
314 // NOTE: It's already verified in Java side that the SVG render area and |
|
315 // the clip area intersects each other |
|
316 aViewbox.Intersection(aRr); |
|
317 |
|
318 // Check if the clip rect has changes the svg rect |
|
319 if (aViewbox.iTl != aAnchor) |
|
320 { |
|
321 // Update anchor position |
|
322 TPoint oldAnchor(aAnchor); |
|
323 aAnchor = aViewbox.iTl; |
|
324 |
|
325 // Update svg rect |
|
326 aViewbox.Move((-oldAnchor.iX), (-oldAnchor.iY)); |
|
327 } |
|
328 else |
|
329 { |
|
330 // The clip rect has not changed the svg rect. Only the |
|
331 // anchor position need to be updated |
|
332 aViewbox.Move(-aAnchor.iX, -aAnchor.iY); |
|
333 } |
|
334 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::PrepareViewbox() - end"); |
|
335 } |
|
336 // ----------------------------------------------------------------------------- |
|
337 // CM2GRenderContext::RenderL |
|
338 // ----------------------------------------------------------------------------- |
|
339 /** |
|
340 * @see CBitmapContext::BitBltMasked() |
|
341 * @note CBitmapContext::BitBltMasked() does alpha blending if the provided mask is 256 and not null, |
|
342 * and simply blits otherwise |
|
343 */ |
|
344 void CM2GRenderContext::RenderLCDUIL( |
|
345 TM2GSvgDocumentHandle& aSvgDocHandle, |
|
346 TReal32 aCurrentTime, |
|
347 const TRect& aViewbox, |
|
348 const TPoint& aAnchor |
|
349 ) |
|
350 { |
|
351 M2G_DEBUG_4("M2G_DEBUG: CM2GRenderContext::RenderL() viewbox: x=%d, y=%d, w=%d, h=%d begin", aViewbox.iTl.iX, aViewbox.iTl.iY, aViewbox.Size().iWidth, aViewbox.Size().iHeight); |
|
352 |
|
353 // No need to render if content is fully transparency (i.e. alpha=0) |
|
354 if (iScaledAlpha == 0) |
|
355 { |
|
356 return; |
|
357 } |
|
358 |
|
359 // 0: clear the previous rendered image |
|
360 ClearBitmapL(iImgBmp); |
|
361 |
|
362 // 1: render the svg document on the iImgBmp |
|
363 iProxy->RenderDocumentL( |
|
364 iEngineHandle, |
|
365 aSvgDocHandle, |
|
366 GetImgHandleL(), NULL, aCurrentTime); |
|
367 |
|
368 CFbsBitmap* mask = NULL; |
|
369 |
|
370 // 2: calculate mask if alpha-blending is used |
|
371 if (iScaledAlpha < MM2GRenderContext::KMaxAlphaValue) |
|
372 { |
|
373 // mask is always the same size as the viewbox |
|
374 CreateAlphaBlendMaskL(aViewbox.Size()); |
|
375 |
|
376 mask = iMaskBmp; // use this mask for alpha blending |
|
377 } |
|
378 |
|
379 // 3: blit the rendered image on the target bitmap |
|
380 // it will do alpha blending when mask is not null |
|
381 M2GBitmapUtils::BitBlt(*iTargetBmp, |
|
382 *iImgBmp, |
|
383 aAnchor, |
|
384 &aViewbox, |
|
385 mask); |
|
386 |
|
387 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::RenderL() end"); |
|
388 } |
|
389 |
|
390 // ----------------------------------------------------------------------------- |
|
391 void CM2GRenderContext::RenderESWTL( |
|
392 TM2GSvgDocumentHandle& aSvgDocHandle, |
|
393 TReal32 aCurrentTime, |
|
394 const TRect& aViewbox, |
|
395 const TPoint& aAnchor, |
|
396 MSwtClient* /*aClientHandle*/, |
|
397 TBool /*aUseNativeClear*/, |
|
398 TInt* aReturnData) |
|
399 { |
|
400 M2G_DEBUG_4("M2G_DEBUG: CM2GRenderContext::RenderL() viewbox: x=%d, y=%d, w=%d, h=%d begin", aViewbox.iTl.iX, aViewbox.iTl.iY, aViewbox.Size().iWidth, aViewbox.Size().iHeight); |
|
401 |
|
402 // No need to render if content is fully transparency (i.e. alpha=0) |
|
403 if (iScaledAlpha == 0) |
|
404 { |
|
405 return; |
|
406 } |
|
407 |
|
408 // 0: clear the previous rendered image |
|
409 ClearBitmapL(iImgBmp); |
|
410 |
|
411 // 1: render the svg document on the iImgBmp |
|
412 iProxy->RenderDocumentL( |
|
413 iEngineHandle, |
|
414 aSvgDocHandle, |
|
415 GetImgHandleL(), NULL, aCurrentTime); |
|
416 |
|
417 CFbsBitmapHack* tempImgBmp = new(ELeave) CFbsBitmapHack(); |
|
418 tempImgBmp->Create(aViewbox.Size(), iImgBmp->DisplayMode()); |
|
419 ClearBitmapL(tempImgBmp); |
|
420 |
|
421 M2GBitmapUtils::BitBlt(*tempImgBmp, |
|
422 *iImgBmp, |
|
423 aAnchor, |
|
424 &aViewbox, |
|
425 NULL); |
|
426 aReturnData[0] = tempImgBmp->Handle(); |
|
427 aReturnData[1] = tempImgBmp->GetMyHandle(); |
|
428 tempImgBmp = NULL; |
|
429 |
|
430 // 2: calculate mask if alpha-blending is used |
|
431 if (iScaledAlpha < MM2GRenderContext::KMaxAlphaValue) |
|
432 { |
|
433 // mask is always the same size as the viewbox |
|
434 CreateAlphaBlendMaskL(aViewbox.Size()); |
|
435 |
|
436 if (iMaskBmp) |
|
437 { |
|
438 CFbsBitmapHack* tempMaskBmp = new(ELeave) CFbsBitmapHack(); |
|
439 tempMaskBmp->Create(aViewbox.Size(), iMaskBmp->DisplayMode()); |
|
440 ClearBitmapL(tempMaskBmp); |
|
441 |
|
442 M2GBitmapUtils::BitBlt(*tempMaskBmp, |
|
443 *iMaskBmp, |
|
444 aAnchor, |
|
445 &aViewbox, |
|
446 NULL); |
|
447 |
|
448 aReturnData[2] = tempMaskBmp->Handle(); |
|
449 aReturnData[3] = tempMaskBmp->GetMyHandle(); |
|
450 tempMaskBmp = NULL; |
|
451 } |
|
452 } |
|
453 |
|
454 // Is this needed ?? |
|
455 //iImgBmp = NULL; |
|
456 //iMaskBmp = NULL; |
|
457 |
|
458 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::RenderL() end"); |
|
459 } |
|
460 // CM2GRenderContext::CreateAlphaBlendMask |
|
461 // ----------------------------------------------------------------------------- |
|
462 /** |
|
463 * <li> mask is initialized with iScaledAlpha for all pixels. |
|
464 * <li> reset the mask for those pixels that are not rendered (a = 0). |
|
465 * <li> due to anti-aliasing (a != 1), |
|
466 * recompute the mask by combining the pixel's alpha with the whole image alpha |
|
467 * |
|
468 * @note The svg backbuffer area is larger than the viewbox |
|
469 * @note The size of the mask is the same as for SVG backbuffer |
|
470 */ |
|
471 void CM2GRenderContext::CreateAlphaBlendMaskL(const TSize& aViewBox) |
|
472 { |
|
473 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::CreateAlphaBlendMaskL() - begin"); |
|
474 |
|
475 // the mask will have the same size as the svg image bitmap |
|
476 // allocate memory for mask according to the size |
|
477 // and initializes it with iScaledAlpha for each pixel ( i.e. Mem::Fill() = fast operation ) |
|
478 InitMaskL(iImgBmp->SizeInPixels()); |
|
479 |
|
480 // lock svg buffer and mask bitmaps |
|
481 TM2GBitmapLock maskLock(iMaskBmp); |
|
482 TM2GBitmapLock imgLock(iImgBmp); |
|
483 |
|
484 TUint8* maskDataPtr = REINTERPRET_CAST(TUint8*, iMaskBmp->DataAddress()); |
|
485 const TUint32* imgDataPtr = iImgBmp->DataAddress(); |
|
486 |
|
487 // Each row of CFbsBitmap is aligned to a 4 bytes boundary |
|
488 // if the mask width in pixels is not a multiple of 4, then we must align the pointer |
|
489 // to the correct address corresponding to the first pixel on the line below |
|
490 |
|
491 TInt maskMaxWidthBytes = iMaskBmp->ScanLineLength( |
|
492 iMaskBmp->SizeInPixels().iWidth, KMaskDisplayMode); |
|
493 |
|
494 const TInt maskDeltaIndex = maskMaxWidthBytes - aViewBox.iWidth; |
|
495 |
|
496 // the svg backbuffer width could be larger than the viewbox width |
|
497 const TInt imgDeltaIndex = iImgBmp->SizeInPixels().iWidth - aViewBox.iWidth; |
|
498 |
|
499 // how many pixels from the viewbox will be rechecked for alpha value |
|
500 const TUint32 countViewBoxPixels = aViewBox.iHeight * aViewBox.iWidth; |
|
501 |
|
502 TUint32 imgAlphaMSB; |
|
503 TUint32 imgAlpha32; |
|
504 TUint32 index = 0; |
|
505 |
|
506 while (index < countViewBoxPixels) |
|
507 { |
|
508 // get the alpha channel in the most left octet (MSB) within a 4 octet |
|
509 imgAlphaMSB = *imgDataPtr & 0xFF000000; |
|
510 |
|
511 if (imgAlphaMSB == 0x0) |
|
512 { |
|
513 // pixel is not rendered so we mask it out |
|
514 *maskDataPtr = 0x0; |
|
515 } |
|
516 else if (imgAlphaMSB != 0xFF000000) |
|
517 { |
|
518 // combine the pixel's alpha with the whole image's alpha (iScaledAlpha) |
|
519 // we are not sure if shifting to right pads it with 0 to the left |
|
520 |
|
521 imgAlpha32 = (imgAlphaMSB >> 24) & 0xFF; |
|
522 |
|
523 // compute the combined alpha on 32b because of possible overflow, |
|
524 // and then downcast to TUint8 |
|
525 // iScaledAlpha = 8b, KMaxAlphaValue = 8b |
|
526 |
|
527 *maskDataPtr = TUint8( |
|
528 (imgAlpha32 * iScaledAlpha) / MM2GRenderContext::KMaxAlphaValue); |
|
529 } |
|
530 |
|
531 imgDataPtr++; |
|
532 maskDataPtr++; |
|
533 index++; |
|
534 |
|
535 // synchronize the image and mask indexes because the viewbox could be smaller than the image/mask |
|
536 if (index % aViewBox.iWidth == 0) |
|
537 { |
|
538 imgDataPtr += imgDeltaIndex; |
|
539 maskDataPtr += maskDeltaIndex; |
|
540 } |
|
541 } |
|
542 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::CreateAlphaBlendMaskL() - end"); |
|
543 } |
|
544 |
|
545 // ----------------------------------------------------------------------------- |
|
546 // CM2GRenderContext::ClearBitmapL |
|
547 // ----------------------------------------------------------------------------- |
|
548 void CM2GRenderContext::ClearBitmapL(CFbsBitmap* aBmp) |
|
549 { |
|
550 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::ClearBitmap - begin"); |
|
551 |
|
552 User::LeaveIfNull(aBmp); |
|
553 |
|
554 TM2GBitmapLock lock(aBmp); |
|
555 |
|
556 TSize size = aBmp->SizeInPixels(); |
|
557 TInt scanlineLength = aBmp->ScanLineLength(size.iWidth, aBmp->DisplayMode()); |
|
558 |
|
559 TUint32* buf = aBmp->DataAddress(); |
|
560 char* bufBytes = REINTERPRET_CAST(char*, buf); |
|
561 |
|
562 Mem::FillZ(bufBytes, size.iHeight * scanlineLength); |
|
563 |
|
564 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::ClearBitmap - end"); |
|
565 } |
|
566 |
|
567 // ----------------------------------------------------------------------------- |
|
568 // CM2GRenderContext::FillBitmapL |
|
569 // ----------------------------------------------------------------------------- |
|
570 void CM2GRenderContext::FillBitmapL(CFbsBitmap* aBmp, const TUint8& aChar) |
|
571 { |
|
572 M2G_DEBUG_1("M2G_DEBUG: CM2GRenderContext::FillBitmap() filled with=%d - begin", aChar); |
|
573 |
|
574 User::LeaveIfNull(aBmp); |
|
575 |
|
576 TM2GBitmapLock lock(aBmp); |
|
577 |
|
578 TSize size = aBmp->SizeInPixels(); |
|
579 TInt scanlineLength = aBmp->ScanLineLength(size.iWidth, aBmp->DisplayMode()); |
|
580 |
|
581 TUint32* buf = aBmp->DataAddress(); |
|
582 char* bufBytes = REINTERPRET_CAST(char*, buf); |
|
583 |
|
584 Mem::Fill(bufBytes, size.iHeight * scanlineLength, aChar); |
|
585 |
|
586 M2G_DEBUG_0("M2G_DEBUG: CM2GRenderContext::FillBitmap - end"); |
|
587 } |
|
588 |
|
589 M2G_NS_END |