|
1 // Copyright (c) 2004-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 /** @file |
|
17 @internalTechnology */ |
|
18 #include <fbs.h> |
|
19 #include "MngPanic.h" |
|
20 |
|
21 #include "MngRenderer.h" |
|
22 |
|
23 /** |
|
24 the color will be used as a "default" to clear background if an image doesn't |
|
25 have one defined and there is no alpha channel |
|
26 */ |
|
27 const TUint KDefaultColor=0; |
|
28 |
|
29 /*static*/ |
|
30 CMngRenderer* CMngRenderer::NewL(const TSize& aSize, TBool aAlphaNeeded, TDisplayMode aDestDisplayMode, TDisplayMode aMaskDisplayMode) |
|
31 { |
|
32 CMngRenderer* self=new (ELeave) CMngRenderer(aSize, aAlphaNeeded, aDestDisplayMode, aMaskDisplayMode); |
|
33 CleanupStack::PushL(self); |
|
34 self->ConstructL(); |
|
35 CleanupStack::Pop(self); |
|
36 return self; |
|
37 } |
|
38 |
|
39 CMngRenderer::CMngRenderer(const TSize& aSize, TBool aAlphaNeeded, TDisplayMode aDestDisplayMode, TDisplayMode aMaskDisplayMode) |
|
40 : iAlphaNeeded(aAlphaNeeded), |
|
41 iRenderSize(aSize), |
|
42 iDestDisplayMode(aDestDisplayMode), |
|
43 iMaskDisplayMode(aMaskDisplayMode) |
|
44 { |
|
45 } |
|
46 |
|
47 void CMngRenderer::ConstructL() |
|
48 { |
|
49 TInt pixelSize; |
|
50 CRgbPixelConsumer::SetPixelFunc setPixelFunction; |
|
51 if(iDestDisplayMode == EColor16MA || iDestDisplayMode == EColor16MU) |
|
52 { |
|
53 pixelSize = KRgbaPixelSize; |
|
54 setPixelFunction = &CRgbPixelConsumer::SetRGBAPixel; |
|
55 } |
|
56 else |
|
57 { |
|
58 pixelSize = KRgbPixelSize; |
|
59 setPixelFunction = &CRgbPixelConsumer::SetRGBPixel; |
|
60 } |
|
61 |
|
62 iRgbConsumer = new (ELeave) CRgbPixelConsumer(pixelSize); |
|
63 iRgbConsumer->InitL(iRenderSize); |
|
64 |
|
65 if (iAlphaNeeded) // as required by source image |
|
66 { |
|
67 iAlphaConsumer= new (ELeave) CAlphaPixelConsumer(); |
|
68 iAlphaConsumer->InitL(iRenderSize); |
|
69 |
|
70 if (iDestDisplayMode == EColor16MA && iMaskDisplayMode != EGray256) // No mask |
|
71 { |
|
72 // In this case, there is a single 16MA destination, so we need to put the |
|
73 // alpha data into the alpha channel, rather than 0xFF. |
|
74 iRgbConsumer->SetAlphaEnabledBitmap(ETrue); |
|
75 } |
|
76 } |
|
77 iRgbConsumer->SetAlphaConsumer(iAlphaConsumer); |
|
78 |
|
79 iRgbProcessor=CRgbProcessor::NewL(this); |
|
80 iRgbProcessor->SetPixelConsumer(iRgbConsumer); |
|
81 iRgbProcessor->SetPixelFunction(setPixelFunction); |
|
82 |
|
83 CAlphaProcessor* Alpha= NULL; |
|
84 if (iAlphaNeeded) |
|
85 { |
|
86 Alpha = CAlphaProcessor::NewL(); |
|
87 iAlphaProcessor = Alpha; |
|
88 Alpha->SetPixelConsumer(iAlphaConsumer); |
|
89 } |
|
90 } |
|
91 |
|
92 CMngRenderer::~CMngRenderer() |
|
93 { |
|
94 delete iRgbProcessor; |
|
95 delete iAlphaProcessor; |
|
96 |
|
97 if (NULL != iRgbFilter) |
|
98 { |
|
99 iRgbFilter->Release(); |
|
100 iRgbFilter = NULL; |
|
101 } |
|
102 delete iRgbConsumer; |
|
103 delete iAlphaConsumer; |
|
104 } |
|
105 |
|
106 void CMngRenderer::Reset() |
|
107 { |
|
108 SetOutputEnabled(ETrue); |
|
109 iBgColourSet = EFalse; |
|
110 iBgColourIsMandatory = EFalse; |
|
111 iBgColour = KDefaultColor; |
|
112 const TPoint KZero(0,0); |
|
113 iViewPortOrigin = KZero; |
|
114 iClippingRect = TRect(KZero, iRenderSize.AsPoint()); |
|
115 iImageClipRect = iClippingRect; |
|
116 iBgClipRect = iClippingRect; |
|
117 |
|
118 // Subframes with No Loops |
|
119 // updated rect as empty |
|
120 UpdateRectEmpty(); |
|
121 // |
|
122 |
|
123 iRgbConsumer->SetClippingRect(iClippingRect); |
|
124 iRgbConsumer->SetOrigin(KZero); |
|
125 |
|
126 ImageProcessor().SetPos(KZero); |
|
127 ImageProcessor().SetYPosIncrement(1); |
|
128 |
|
129 if (iAlphaConsumer) |
|
130 { |
|
131 iAlphaConsumer->SetClippingRect(iClippingRect); |
|
132 iAlphaConsumer->SetOrigin(KZero); |
|
133 } |
|
134 } |
|
135 |
|
136 /* |
|
137 Clears the current layer clipping rect |
|
138 */ |
|
139 void CMngRenderer::ClearOutputRect() |
|
140 { |
|
141 UpdateRect(iBgClipRect); |
|
142 |
|
143 if (iBgColourSet && iBgColourIsMandatory) |
|
144 { |
|
145 iRgbConsumer->Clear( iBgColour, iBgClipRect ); |
|
146 if (iAlphaConsumer) |
|
147 { |
|
148 iAlphaConsumer->Clear(KOpaqueAlpha, iBgClipRect); |
|
149 } |
|
150 } |
|
151 else |
|
152 { |
|
153 if (iAlphaConsumer) |
|
154 { |
|
155 iAlphaConsumer->Clear(KTransparentAlpha, iBgClipRect); |
|
156 if (iDestDisplayMode == EColor16MA && iMaskDisplayMode != EGray256) |
|
157 { |
|
158 iRgbConsumer->ClearAlpha(KTransparentAlpha, iBgClipRect); |
|
159 } |
|
160 } |
|
161 else |
|
162 { |
|
163 // no alpha, so clear by available color |
|
164 iRgbConsumer->Clear(iBgColour, iBgClipRect ); |
|
165 } |
|
166 } |
|
167 } |
|
168 |
|
169 void CMngRenderer::OnNewImageL() |
|
170 { |
|
171 if (iAlphaConsumer) |
|
172 { |
|
173 iAlphaConsumer->SetEnabled(EFalse); |
|
174 } |
|
175 } |
|
176 |
|
177 void CMngRenderer::SetBackground(const TRgb aBgColour, TBool aColourIsMandatory) |
|
178 { |
|
179 iBgColour = aBgColour.Internal(); |
|
180 iBgColourIsMandatory= aColourIsMandatory; |
|
181 iBgColourSet= ETrue; |
|
182 } |
|
183 |
|
184 void CMngRenderer::SetImageOrigin(const TPoint& aOrigin) |
|
185 { |
|
186 iViewPortOrigin = aOrigin; |
|
187 iRgbConsumer->SetOrigin(aOrigin); |
|
188 if (iAlphaConsumer) |
|
189 { |
|
190 iAlphaConsumer->SetOrigin(aOrigin); |
|
191 } |
|
192 } |
|
193 |
|
194 void CMngRenderer::SetImageClipRect(const TRect& aClippingRect) |
|
195 { |
|
196 iImageClipRect = aClippingRect; |
|
197 iClippingRect = aClippingRect; |
|
198 iClippingRect.Intersection(iBgClipRect); |
|
199 |
|
200 iRgbConsumer->SetClippingRect(iClippingRect); |
|
201 if (iAlphaConsumer) |
|
202 { |
|
203 iAlphaConsumer->SetClippingRect(iClippingRect); |
|
204 } |
|
205 } |
|
206 |
|
207 void CMngRenderer::SetBgClipRect(const TRect& aClippingRect) |
|
208 { |
|
209 iBgClipRect = aClippingRect; |
|
210 iBgClipRect.Intersection(TRect(TPoint(0,0), iRenderSize.AsPoint())); |
|
211 iClippingRect = iBgClipRect; |
|
212 iClippingRect.Intersection(iImageClipRect); |
|
213 |
|
214 iRgbConsumer->SetClippingRect(iClippingRect); |
|
215 if (iAlphaConsumer) |
|
216 { |
|
217 iAlphaConsumer->SetClippingRect(iClippingRect); |
|
218 } |
|
219 } |
|
220 |
|
221 void CMngRenderer::SetRgbFilter(MPixelFilter* aPixelFilter) |
|
222 { |
|
223 if (NULL != iRgbFilter) |
|
224 { |
|
225 iRgbFilter->Release(); |
|
226 } |
|
227 if (NULL != aPixelFilter) |
|
228 { |
|
229 aPixelFilter->AddRef(); |
|
230 } |
|
231 iRgbFilter = aPixelFilter; |
|
232 iRgbProcessor->SetPixelFilter(aPixelFilter); |
|
233 } |
|
234 |
|
235 //Subframes with No Loops |
|
236 void CMngRenderer::UpdateRect(const TRect& aRect) |
|
237 { |
|
238 /** Top Left Minima */ |
|
239 if(iUpdateRect.iTl.iX > aRect.iTl.iX ) |
|
240 { |
|
241 iUpdateRect.iTl.iX = aRect.iTl.iX; |
|
242 } |
|
243 |
|
244 if(iUpdateRect.iTl.iY > aRect.iTl.iY) |
|
245 { |
|
246 iUpdateRect.iTl.iY = aRect.iTl.iY; |
|
247 } |
|
248 |
|
249 /** Bottom Right Maxima */ |
|
250 if(iUpdateRect.iBr.iX < aRect.iBr.iX ) |
|
251 { |
|
252 iUpdateRect.iBr.iX = aRect.iBr.iX; |
|
253 } |
|
254 |
|
255 if(iUpdateRect.iBr.iY < aRect.iBr.iY) |
|
256 { |
|
257 iUpdateRect.iBr.iY = aRect.iBr.iY; |
|
258 } |
|
259 } |
|
260 |
|
261 void CMngRenderer::UpdateRectEmpty() |
|
262 { |
|
263 const TPoint KZero(0,0); |
|
264 iUpdateRect.iBr = KZero; |
|
265 iUpdateRect.iTl = iRenderSize.AsPoint(); |
|
266 } |
|
267 // |
|
268 |
|
269 // from the CImageProcessor // |
|
270 |
|
271 TBool CPixelProcessor::SetPixelBlock(TRgb* /*aColorBuffer*/) |
|
272 { |
|
273 ASSERT(EFalse); |
|
274 return EFalse; |
|
275 } |
|
276 |
|
277 TBool CPixelProcessor::SetPixels(TRgb* /*aColorBuffer*/,TInt /*aBufferLength*/) |
|
278 { |
|
279 ASSERT(EFalse); |
|
280 return EFalse; |
|
281 } |
|
282 |
|
283 TBool CPixelProcessor::SetMonoPixel(TInt /*aGray256*/) |
|
284 { |
|
285 ASSERT(EFalse); |
|
286 return EFalse; |
|
287 } |
|
288 |
|
289 TBool CPixelProcessor::SetMonoPixelRun(TInt /*aGray256*/,TInt /*aCount*/) |
|
290 { |
|
291 ASSERT(EFalse); |
|
292 return EFalse; |
|
293 } |
|
294 |
|
295 TBool CPixelProcessor::SetMonoPixels(TUint32* /*aGray256Buffer*/,TInt /*aBufferLength*/) |
|
296 { |
|
297 ASSERT(EFalse); |
|
298 return EFalse; |
|
299 } |
|
300 |
|
301 TBool CPixelProcessor::SetMonoPixelBlock(TUint32* /*aGray256Buffer*/) |
|
302 { |
|
303 ASSERT(EFalse); |
|
304 return EFalse; |
|
305 } |
|
306 |
|
307 TBool CPixelProcessor::SetPos(const TPoint& aPosition) |
|
308 { |
|
309 iPixelPosition = aPosition; |
|
310 return ETrue; |
|
311 } |
|
312 |
|
313 TBool CPixelProcessor::FlushPixels() |
|
314 { |
|
315 if (NULL != iPixelFilter) |
|
316 { |
|
317 iPixelFilter->Commit(); |
|
318 } |
|
319 return ETrue; |
|
320 } |
|
321 |
|
322 void CPixelProcessor::PrepareL(CFbsBitmap& /*aBitmap*/,const TRect& aImageRect) |
|
323 { |
|
324 iCurrentImgSize = aImageRect.Size(); |
|
325 iPixelsToSkip = iPixelPadding; |
|
326 iYInc = 1; |
|
327 iPixelPosition.SetXY(0,0); |
|
328 if (NULL != iPixelConsumer) |
|
329 { |
|
330 iPixelConsumer->Prepare(); |
|
331 } |
|
332 if (NULL != iPixelFilter) |
|
333 { |
|
334 iPixelFilter->PrepareL(iCurrentImgSize, static_cast<CRgbPixelConsumer*>(iPixelConsumer) ); |
|
335 } |
|
336 } |
|
337 |
|
338 void CPixelProcessor::PrepareL(CFbsBitmap& /*aBitmap*/,const TRect& /*aImageRect*/,const TSize& /*aRgbBlockSize*/) |
|
339 { |
|
340 ASSERT(EFalse); |
|
341 } |
|
342 |
|
343 void CPixelProcessor::SetYPosIncrement(TInt aYInc) |
|
344 { |
|
345 iYInc = aYInc; |
|
346 } |
|
347 |
|
348 void CPixelProcessor::SetLineRepeat(TInt /*aLineRepeat*/) |
|
349 { |
|
350 // we don't use progressive decoding |
|
351 } |
|
352 |
|
353 void CPixelProcessor::SetPixelPadding(TInt aNumberOfPixels) |
|
354 { |
|
355 iPixelPadding = aNumberOfPixels; |
|
356 } |
|
357 |
|
358 /*static*/ |
|
359 CRgbProcessor* CRgbProcessor::NewL(CMngRenderer* aMngRenderer) |
|
360 { |
|
361 return new (ELeave) CRgbProcessor(aMngRenderer); |
|
362 } |
|
363 |
|
364 CRgbProcessor::CRgbProcessor(CMngRenderer* aMngRenderer):iMngRenderer(aMngRenderer) |
|
365 { |
|
366 } |
|
367 |
|
368 |
|
369 TBool CRgbProcessor::SetPixels(TRgb* aColorBuffer,TInt aBufferLength) |
|
370 { |
|
371 ASSERT(aBufferLength>0); |
|
372 if (aBufferLength > iPixelsToSkip) |
|
373 { |
|
374 aBufferLength -= iPixelsToSkip; |
|
375 iPixelsToSkip = 0; |
|
376 if (iPixelFilter==NULL) |
|
377 { |
|
378 do |
|
379 { |
|
380 SetPixelImpl(*aColorBuffer++); |
|
381 } while (--aBufferLength > 0); |
|
382 } |
|
383 else |
|
384 { |
|
385 do |
|
386 { |
|
387 SetPixelImplWithPf(*aColorBuffer++); |
|
388 } while (--aBufferLength > 0); |
|
389 } |
|
390 } |
|
391 else |
|
392 { |
|
393 iPixelsToSkip -= aBufferLength; |
|
394 } |
|
395 return ETrue; |
|
396 } |
|
397 |
|
398 TBool CRgbProcessor::SetPixelRun(TRgb aColor,TInt aCount) |
|
399 { |
|
400 if (aCount > iPixelsToSkip) |
|
401 { |
|
402 aCount -= iPixelsToSkip; |
|
403 iPixelsToSkip = 0; |
|
404 if (iPixelFilter==NULL) |
|
405 { |
|
406 do |
|
407 { |
|
408 SetPixelImpl(aColor); |
|
409 } while (--aCount); |
|
410 } |
|
411 else |
|
412 { |
|
413 do |
|
414 { |
|
415 SetPixelImplWithPf(aColor); |
|
416 } while (--aCount); |
|
417 } |
|
418 } |
|
419 else |
|
420 { |
|
421 iPixelsToSkip -= aCount; |
|
422 } |
|
423 return ETrue; |
|
424 } |
|
425 |
|
426 //Subframes with No Loops |
|
427 //added here |
|
428 void CRgbProcessor::PrepareL(CFbsBitmap& aBitmap,const TRect& aImageRect) |
|
429 { |
|
430 //updation with this new image. new image rect is defined by OriginSet(iViewPortOrigin) and OriginSet+Bottom right calc from aImageRect size |
|
431 TSize imageSize(aImageRect.Width(), aImageRect.Height()); |
|
432 TRect imageRect(iMngRenderer->ViewPortOrigin(),imageSize); |
|
433 imageRect.Intersection(iMngRenderer->ClippingRect()); //Bug fix |
|
434 iMngRenderer->UpdateRect(imageRect); |
|
435 |
|
436 CPixelProcessor::PrepareL(aBitmap, aImageRect); |
|
437 } |
|
438 // |
|
439 |
|
440 TBool CRgbProcessor::SetPixel(TRgb aColor) |
|
441 { |
|
442 if (iPixelsToSkip) |
|
443 { |
|
444 --iPixelsToSkip; |
|
445 return ETrue; |
|
446 } |
|
447 return iPixelFilter==NULL? SetPixelImpl(aColor) : SetPixelImplWithPf(aColor); |
|
448 } |
|
449 |
|
450 inline |
|
451 TBool CRgbProcessor::SetPixelImplWithPf(TRgb aColor) |
|
452 { |
|
453 iPixelFilter->SetPixel(iPixelPosition, aColor.Internal()); |
|
454 |
|
455 if (++iPixelPosition.iX == iCurrentImgSize.iWidth) |
|
456 { |
|
457 iPixelPosition.iX = 0; |
|
458 iPixelPosition.iY += iYInc; |
|
459 iPixelsToSkip = iPixelPadding; |
|
460 } |
|
461 return ETrue; |
|
462 } |
|
463 |
|
464 inline |
|
465 TBool CRgbProcessor::SetPixelImpl(TRgb aColor) |
|
466 { |
|
467 iPixelConsumer->SetPos(iPixelPosition); |
|
468 CALL_SETPIXEL_FUNCTION(*Consumer(), iSetPixelFunction)(TRgbaColour(aColor.Internal())); |
|
469 |
|
470 if (++iPixelPosition.iX == iCurrentImgSize.iWidth) |
|
471 { |
|
472 iPixelPosition.iX = 0; |
|
473 iPixelPosition.iY += iYInc; |
|
474 iPixelsToSkip = iPixelPadding; |
|
475 } |
|
476 |
|
477 return ETrue; |
|
478 } |
|
479 |
|
480 |
|
481 /*static*/ |
|
482 CAlphaProcessor* CAlphaProcessor::NewL() |
|
483 { |
|
484 return new (ELeave) CAlphaProcessor(); |
|
485 } |
|
486 |
|
487 void CAlphaProcessor::PrepareL(CFbsBitmap& aBitmap, const TRect& aImageRect) |
|
488 { |
|
489 CPixelProcessor::PrepareL(aBitmap, aImageRect); |
|
490 if (Consumer()) |
|
491 { |
|
492 Consumer()->SetEnabled(ETrue); |
|
493 } |
|
494 } |
|
495 |
|
496 TBool CAlphaProcessor::SetPixelRun(TRgb /*aColor*/,TInt /*aCount*/) |
|
497 { |
|
498 ASSERT(EFalse); |
|
499 return EFalse; |
|
500 } |
|
501 |
|
502 TBool CAlphaProcessor::SetPixel(TRgb /*aColor*/) |
|
503 { |
|
504 ASSERT(EFalse); |
|
505 return EFalse; |
|
506 } |
|
507 |