First public contribution.
1 // Copyright (c) 2006-2010 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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include <graphics/lookuptable.h>
18 #include <graphics/blendingalgorithms.h>
21 Does the same conversion as NonPMA2PMAPixel, but leaves the values in the RB and G uint32 values
22 ready for use in the blending algorithm. Also assumes alphas of 0 or 0xFF have already been
23 stripped out as special cases.
25 FORCEINLINE void NonPMA2PMAPixelRBG(TUint32 aPixel, TUint32 &aSrcRB, TUint32 &aSrcG, TUint32 &aMask)
27 TUint32 alpha=(aPixel >> 24);
28 aMask = 0x0100 - alpha; // for use in PMABlend_fromRBandG
30 aSrcRB = (aPixel & KRBMask) * tap1;
33 aSrcG = (aPixel&0xFF000000) | (((aPixel & KGMask)>>8) * tap1) & KAGMask;
37 Uses same algorithm as PMABlend_noChecksInplace, but optimised for use with NonPMA2PMAPixelRBG where
38 source values are pre-split into RB and G components ready for use in blend
40 FORCEINLINE void PMABlend_fromRBandG(TUint32& aDest_io, const TUint32 aSrcRB, const TUint32 aSrcG, const TUint8 aMask)
42 TUint32 dst_ag = (aDest_io & KAGMask) >> 8;
43 aDest_io = aDest_io & KRBMask;
44 aDest_io = (aSrcRB + ((aMask * aDest_io) >> 8)) & KRBMask;
45 aDest_io |= (aSrcG + (aMask * dst_ag)) & KAGMask;
49 Takes a non-PM source colour and an alpha value
50 First pre-multiplies aSrcPixel with aAlpha
51 Then blends it into aDestIo using the same alpha value.
53 FORCEINLINE void PMABlend_FromNonPmAndAlpha(TUint32& aDest_io, const TUint32& aSrcPixel, TUint32 aAlpha)
55 TUint32 tap1=aAlpha+1;
56 TUint32 srcRB = (aSrcPixel & KRBMask) * tap1;
57 srcRB=(srcRB>>8) & KRBMask;
58 TUint32 srcAG = (aSrcPixel & KGMask ) * tap1;
59 srcAG=(srcAG>>8) & KGMask;
62 TUint32 dst_ag = (aDest_io & KAGMask) >> 8;
63 TUint32 dst_rb = aDest_io & KRBMask;
64 const TUint32 mask = 0x0100 - aAlpha;
65 aDest_io = (srcRB + ((mask*dst_rb) >> 8)) & KRBMask;
66 aDest_io |= (srcAG + mask*dst_ag) & KAGMask;
69 // Same as NonPMA2PMAPixel, but for use where checks for alpha of 0 or 0xFF have already been done
70 FORCEINLINE TUint32 NonPMA2PMAPixelNoCheck(TUint32 aPixel)
72 TUint32 tap1=(aPixel>>24)+1;
73 TUint32 scaledRB = (aPixel & KRBMask) * tap1;
74 TUint32 scaledG = (aPixel & KGMask ) * tap1;
75 return (aPixel & 0xff000000) | ((scaledRB>>8) & KRBMask) | ((scaledG>>8)& KGMask);
79 Composite mask application
80 where AlphaComposite = AlphaColor * AlphaMask / 255.
81 @param aColor - non-premltiplied color with alpha
82 @param aMask - the mask value. (0 to 255).
83 @return the color with alpha combined from color and mask (combination
84 operator used is scaled multiplication).
86 FORCEINLINE TUint32 CompMask(TUint32 aColor, TUint8 aMask)
88 // if the mask is FF the colour will be fully opaque and can be immediatly returned
92 TUint32 cAlpha = (aMask+1) * (aColor >> 24);
93 return ((aColor & 0x00ffffff) | ((cAlpha <<16) & 0xff000000));
96 TInt CDrawThirtyTwoBppBitmapAlphaPM::Construct(TSize aSize)
98 return Construct(aSize, aSize.iWidth << 2);
101 TInt CDrawThirtyTwoBppBitmapAlphaPM::Construct(TSize aSize, TInt aStride)
103 iDispMode = EColor16MAP;
104 return CDrawThirtyTwoBppBitmapCommon::Construct(aSize, aStride);
108 MAlphaBlend::WriteRgbAlphaLine() implementation.
109 Blends the supplied buffer of TRgb format data (ARGB), and the mask, to the destination
110 which is specified by the pixel positions aX, aY and length.
111 @param aX The starting position on the x-axis for the destination pixel.
112 @param aY The starting position on the y-axis for the destination pixel.
113 @param aRgbBuffer The RGB source data buffer. This is assumed to be bit aligned 32 bit non-premultiplied data
114 @param aMaskBuffer The masking data. The mask buffer and the source alpha values are multiplied together to
115 generate the alpha used for blending to the destination.
116 @param aShadowing The shadowing flag. Indicates when and how to apply shadowing.
117 @param aDrawMode The mode for rendering the source image to the destination.
118 Currently supports EWriteAlpha and EPenmode.
120 @see MAlphaBlend::WriteRgbAlphaLine()
122 void CDrawThirtyTwoBppBitmapAlphaPM::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
123 const TUint8* aRgbBuffer,
124 const TUint8* aMaskBuffer,
125 MAlphaBlend::TShadowing aShadowing,
126 CGraphicsContext::TDrawMode aDrawMode)
128 // precondition for this function is that the aRgbBuffer lies on a word boundary
129 // Assert checks that the pointer is at a word boundary
130 __ASSERT_DEBUG(!(((TUint)aRgbBuffer) & 0x3), Panic(EScreenDriverPanicInvalidPointer));
133 TUint32* pixelPtr = PixelAddress(aX,aY);
134 const TInt pixelPtrInc = PixelAddressIncrement();
135 const TUint16* normTable = PtrTo16BitNormalisationTable();
137 const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
138 // The purpose of this conditional is to remove if statements from within the loop
139 // if shadow mode is not enabled and the UserDispMode is none or EColor16MAP
140 if(!(iShadowMode & (EFade | EShadow)) && (iUserDispMode ==EColor16MAP || iUserDispMode == ENone))
142 while (aMaskBuffer < maskBufferPtrLimit)
146 TUint32 srcData = *((TUint32*)aRgbBuffer);
147 if ((aDrawMode == CGraphicsContext::EDrawModeWriteAlpha) && (*aMaskBuffer == 0xFF))
149 // Write the source straight through to the target, otherwise
150 // blend. This relies on the fact that EDrawModeWriteAlpha can only
151 // be used with masks that contain only black or white.
152 Convert2PMA(srcData);
157 //blend alpha value in source with the mask value.
158 srcData = CompMask(srcData, *aMaskBuffer);
159 //pre-multiply, inplace.
160 Convert2PMA(srcData);
161 PMAInplaceBlend(*pixelPtr, srcData);
164 pixelPtr += pixelPtrInc;
171 while (aMaskBuffer < maskBufferPtrLimit)
173 TUint32 srcColor = *((TUint32*)(aRgbBuffer));
176 if(aShadowing == MAlphaBlend::EShdwBefore)
178 // src color in non-premultiplied.
179 Shadow(*(TRgb*)&srcColor);
182 if ((aDrawMode == CGraphicsContext::EDrawModeWriteAlpha) && (*aMaskBuffer == 0xFF))
184 Convert2PMA(srcColor);
189 //blend alpha value in source with the mask value.
190 srcData = CompMask(srcColor, *aMaskBuffer);
191 //pre-multiply, inplace.
192 Convert2PMA(srcData);
193 srcData = PMAPixelBlend(*pixelPtr, srcData);
196 if(aShadowing == MAlphaBlend::EShdwAfter)
198 // shadow is done in PMA mode.
201 if(iUserDispMode !=EColor16MAP && iUserDispMode != ENone)
203 tmp.SetInternal(PMA2NonPMAPixel(srcData, normTable));
204 CDrawThirtyTwoBppBitmapCommon::MapColorToUserDisplayMode(tmp);
205 srcData = tmp.Internal();
206 Convert2PMA(srcData);
210 pixelPtr += pixelPtrInc;
218 This assumes that the pen color (aColor) alpha information is to be blended with
219 the alpha provided by the mask buffer.
220 If pen is opaque, the mask is used as transparency information to be used.
221 If pen is semi-transparent, the mask is contructed by calculating the resulting alpha
222 by multiplying the mask with the alpha information of the pen color.
223 @see CFbsDrawDevice::WriteRgbAlphaMulti
225 void CDrawThirtyTwoBppBitmapAlphaPM::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer)
227 TUint32 srcAlpha = aColor.Alpha();
228 if (srcAlpha==0 || aLength<=0)
231 TUint32* pixelPtr = PixelAddress(aX,aY);
232 const TInt pixelPtrInc = PixelAddressIncrement();
233 const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
235 CDrawThirtyTwoBppBitmapCommon::Shadow(aColor);
236 // pre-multiply the color.
237 const TUint32 srcColor = aColor.Internal();
239 { // source (pen) is opaque, so we simply blend it using the mask
240 // little trick to make main loop more optimised, having 'pixelPtr += pixelPtrInc' at the top
241 // of the loop makes the compiler generate better code without extra jumps to reach the
242 // 'pixelPtr += pixelPtrInc' line.
243 // We also need to do the FOREVER loop with a break when aMaskBuffer==maskBufferPtrLimit or
244 // else the compiler puts the test at the end and extra jumps are required to reach it.
245 pixelPtr -= pixelPtrInc;
248 pixelPtr += pixelPtrInc;
249 if (aMaskBuffer==maskBufferPtrLimit)
251 const TUint maskAlpha=*aMaskBuffer++;
253 { // Most pixels in text are blank, so this is the most important route to optimise
256 else if (maskAlpha==0xFF)
257 { // Second most important are fully opaque pixels
261 TUint32 maskColor = NonPMA2PMAPixelNoCheck((srcColor&~0xFF000000) | ((TUint32)maskAlpha << 24));
262 PMAInplaceBlend(*pixelPtr, maskColor);
265 else if(srcAlpha > 0)
267 // pen is semi-transparent, so we must blend using both the mask and pen alpha
268 // pre calculate ffMaskColor optimised for common case where aMaskBuffer contains 0xFF
269 const TUint32 ffMaskColor=NonPMA2PMAPixelNoCheck(srcColor);
270 const TUint32 noAlphaSrcColor=srcColor&0xFFFFFF;
271 while (aMaskBuffer < maskBufferPtrLimit)
273 const TUint maskAlpha=*aMaskBuffer;
277 PMABlend_noChecksInplace(*pixelPtr, ffMaskColor, srcAlpha);
280 TUint32 mixedAlpha = ((maskAlpha+1) * srcAlpha)>>8;
281 PMABlend_FromNonPmAndAlpha(*pixelPtr, noAlphaSrcColor, mixedAlpha);
284 pixelPtr += pixelPtrInc;
291 @see CFbsDrawDevice::WriteRgb
293 void CDrawThirtyTwoBppBitmapAlphaPM::WriteRgb(TInt aX,TInt aY,TRgb aColor)
295 TUint32 srcColor = NonPMA2PMAPixel(aColor.Internal());
296 TUint32* pixelPtr = PixelAddress(aX,aY);
297 PMAInplaceBlend(*pixelPtr, srcColor);
301 @see CFbsDrawDevice::WriteBinary
303 void CDrawThirtyTwoBppBitmapAlphaPM::WriteBinary(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,TInt aHeight,TRgb aColor)
305 const TUint32 colorInternal=aColor.Internal();
306 const TUint8 srcAlpha = colorInternal >> 24;
316 case EOrientationNormal:
319 rowInc = iScanLineWords;
322 case EOrientationRotated90:
324 pixelInc = iScanLineWords;
328 case EOrientationRotated180:
331 rowInc = -iScanLineWords;
334 default: // EOrientationRotated270
336 pixelInc = -iScanLineWords;
341 const TUint32* dataLimit = aBuffer + aHeight;
342 const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
344 TUint32* pixelPtr = PixelAddress(aX,aY);
347 while (aBuffer < dataLimit)
349 TUint32 dataWord = *aBuffer++;
350 TUint32 dataMask = 1;
351 TUint32* tempPixelPtr = pixelPtr;
352 while (dataMask != dataMaskLimit)
354 if(dataWord & dataMask)
356 *tempPixelPtr=colorInternal;
359 tempPixelPtr += pixelInc;
371 //pre-multiply the src color, before blending.
372 NonPMA2PMAPixelRBG(colorInternal,src_rb,src_g,mask);
373 while (aBuffer < dataLimit)
375 TUint32 dataWord = *aBuffer++;
376 TUint32 dataMask = 1;
377 TUint32* tempPixelPtr = pixelPtr;
378 while (dataMask != dataMaskLimit)
380 if(dataWord & dataMask)
382 PMABlend_fromRBandG(*tempPixelPtr, src_rb, src_g, mask);
385 tempPixelPtr += pixelInc;
395 @see CFbsDrawDevice::WriteBinaryLineVertical
397 void CDrawThirtyTwoBppBitmapAlphaPM::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aBuffer,TInt aHeight,TRgb aColor,TBool aUp)
399 const TUint32 colorInternal=aColor.Internal();
400 const TInt sourceAlpha = colorInternal>>24;
406 TInt scanlineWordLength;
410 case EOrientationNormal:
411 scanlineWordLength = iScanLineWords;
413 case EOrientationRotated90:
414 scanlineWordLength = -1;
416 case EOrientationRotated180:
417 scanlineWordLength = -iScanLineWords;
419 default: // EOrientationRotated270
420 scanlineWordLength = 1;
424 scanlineWordLength = -scanlineWordLength;
426 TUint32* pixelPtr = PixelAddress(aX,aY);
427 const TUint32* pixelPtrLimit = pixelPtr + (aHeight * scanlineWordLength);
428 TUint32 dataWord = *aBuffer;
429 TUint32 dataMask = 1;
431 if (sourceAlpha==0xFF)
433 while(pixelPtr != pixelPtrLimit)
442 if(dataWord & dataMask)
444 *pixelPtr = colorInternal;
447 pixelPtr += scanlineWordLength;
455 //pre-multiply the src color, before blending.
456 NonPMA2PMAPixelRBG(colorInternal,src_rb,src_g,mask);
457 while(pixelPtr != pixelPtrLimit)
466 if(dataWord & dataMask)
468 PMABlend_fromRBandG(*pixelPtr, src_rb, src_g, mask);
471 pixelPtr += scanlineWordLength;
477 @see CFbsDrawDevice::BlendRgbMulti
479 void CDrawThirtyTwoBppBitmapAlphaPM::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
481 const TInt sourceAlpha = aColor.Alpha();
482 if (sourceAlpha==255)// opaque
484 WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
487 if (sourceAlpha==0)// transparent
489 TUint32* pixelPtr = PixelAddress(aX,aY);
490 TUint32* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineWords);
491 TUint32* pixelPtrLimit = pixelPtr + aLength;
493 TUint32 srcValue = NonPMA2PMAPixel(aColor.Internal());
494 TUint32 src_c = srcValue & KRBMask;
495 TUint32 src_g = (srcValue & KAGMask)>>8;
496 const TUint32 mask = 0x0100 - sourceAlpha;
497 while (pixelPtr < pixelRowPtrLimit)
499 for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
501 const TUint32 dst = *tempPixelPtr;
502 TUint32 dst_c = dst & KRBMask;
503 dst_c = (src_c + ((mask * dst_c)>>8)) & KRBMask;
504 const TUint32 dst_ag = (dst & KAGMask)>>8;
505 dst_c |= ((src_g + ((mask * dst_ag)>>8)) & KRBMask)<<8;
508 pixelPtr += iScanLineWords;
509 pixelPtrLimit += iScanLineWords;
514 @see CFbsDrawDevice::BlendLine
516 void CDrawThirtyTwoBppBitmapAlphaPM::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
518 TUint32* pixelPtr = PixelAddress(aX,aY);
520 const TUint32* bufferPtrLimit = aBuffer + aLength;
521 const TInt pixelPtrInc = (iOrientation == EOrientationNormal) ? 1 : PixelAddressIncrement();
523 while (aBuffer < bufferPtrLimit)
525 PMAInplaceBlend(*pixelPtr, *aBuffer);
527 pixelPtr += pixelPtrInc;
531 @see CFbsDrawDevice::ShadowArea
533 void CDrawThirtyTwoBppBitmapAlphaPM::ShadowArea(const TRect& aRect)
535 const TRect rect(DeOrientate(aRect));
536 __ASSERT_DEBUG(rect.iTl.iX>=0 && rect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
537 __ASSERT_DEBUG(rect.iTl.iY>=0 && rect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
539 TUint32* pixelPtr = PixelAddress(rect.iTl.iX,rect.iTl.iY);
540 TUint32* pixelRowPtrLimit = pixelPtr + (rect.Height() * iScanLineWords);
542 TUint32* pixelRowPtr = pixelPtr;
543 TUint32* pixelPtrLimit = pixelPtr + rect.Width();
545 if (iShadowMode & EFade)
547 while (pixelRowPtr < pixelRowPtrLimit)
549 TUint32* tempPixelPtr = pixelRowPtr;
551 while (tempPixelPtr < pixelPtrLimit)
553 const TUint32 color = *tempPixelPtr;
554 #if defined(SYMBIAN_USE_FAST_FADING)
555 const TUint32 fast_fade_offset = NonPMA2PMAPixel((color & 0xff000000) | SYMBIAN_USE_FAST_FADING) & 0x00ffffff;
556 *tempPixelPtr++ = (color & 0xff000000) | ((((color & 0x00ffffff) >> 1) & ~0x00808080) + fast_fade_offset);
558 const TInt alpha = (color >> 24) + 1;
559 const TUint32 fadeMapOffset = ((alpha * iFadeMapOffset) >> 8) & 0xff;
560 const TUint32 wordFadeMapOffset = ((fadeMapOffset) << 16) | (fadeMapOffset);
561 const TUint32 rb = ((((color & 0x00ff00ff) * iFadeMapFactor) >> 8) + wordFadeMapOffset) & 0x00ff00ff;
562 const TUint32 g = ((((color & 0x0000ff00) * iFadeMapFactor) >> 16) + fadeMapOffset) << 8;
563 *tempPixelPtr++ = (color & 0xff000000) | rb | g;
566 pixelRowPtr += iScanLineWords;
567 pixelPtrLimit += iScanLineWords;
571 if (iShadowMode & EShadow)
573 pixelRowPtr = pixelPtr;
574 pixelPtrLimit = pixelPtr + rect.Width();
576 while (pixelRowPtr < pixelRowPtrLimit)
578 TUint32* tempPixelPtr = pixelRowPtr;
580 while (tempPixelPtr < pixelPtrLimit)
582 const TUint32 color = *tempPixelPtr;
583 const TInt alpha = (color >> 24) + 1;
584 const TInt uLimit = ((0x40) * alpha) >> 8;
585 TInt r = (color >> 16) & 0xff;
586 r = (r > uLimit) ? (r-uLimit) : 0;
587 TInt g = (color >> 8) & 0xff;
588 g = (g > uLimit) ? (g - uLimit) : 0;
589 TInt b = color & 0xff;
590 b = (b > uLimit) ? (b - uLimit) : 0;
591 *tempPixelPtr++ = (color & 0xff000000) | (r << 16) | (g << 8) | b;
593 pixelRowPtr += iScanLineWords;
594 pixelPtrLimit += iScanLineWords;
600 @see CFbsDrawDevice::WriteLine
602 void CDrawThirtyTwoBppBitmapAlphaPM::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer,
603 CGraphicsContext::TDrawMode aDrawMode)
605 const TPoint originalPoint(aX,aY);
606 DeOrientate(aX,aY);//aX and aY - physical coordinates
608 __ASSERT_DEBUG(aX >= 0,Panic(EScreenDriverPanicOutOfBounds));
609 __ASSERT_DEBUG(aY >= 0,Panic(EScreenDriverPanicOutOfBounds));
611 switch (iOrientation)
613 case EOrientationNormal:
614 __ASSERT_DEBUG(aX + aLength <= iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
616 case EOrientationRotated90:
617 __ASSERT_DEBUG(aY + aLength <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
619 case EOrientationRotated180:
620 __ASSERT_DEBUG(aX - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
622 default: // EOrientationRotated270
623 __ASSERT_DEBUG(aY - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
627 __ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength));
628 __ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
630 MapBufferToUserDisplayMode(aLength,aBuffer);
633 ShadowBuffer(aLength,aBuffer);
635 if(aDrawMode&CGraphicsContext::EInvertPen)
638 // code in CFbsBitGc::DoBitBltMasked() does not require logical operator pen modes in premultiplied alpha screen driver for blitting of icons with masks
639 // RDebug::Printf("Premultiplied alpha mode invert pen behaviour not defined / implemented");
643 if(aDrawMode&CGraphicsContext::EPenmode)
645 BlendLine(aX,aY,aLength,aBuffer);
648 if(aDrawMode&CGraphicsContext::EWriteAlpha)
650 CDrawThirtyTwoBppBitmapCommon::WriteLine(aX,aY,aLength,aBuffer);
653 if(aDrawMode&CGraphicsContext::EInvertScreen)
656 // RDebug::Printf("Premultiplied alpha mode invert screen behaviour not defined / implemented");
658 return; //no-operation
660 if(aDrawMode&CGraphicsContext::EXor)
663 // code in CFbsBitGc::DoBitBltMasked() does not require logical operator pen modes in premultiplied alpha screen driver for blitting of icons with masks
664 // RDebug::Printf("Premultiplied alpha mode XOR operation not defined / implemented");
666 return; //no-operation
668 else if(aDrawMode&CGraphicsContext::EAnd)
671 // code in CFbsBitGc::DoBitBltMasked() does not require logical operator pen modes in premultiplied alpha screen driver for blitting of icons with masks
672 // RDebug::Printf("Premultiplied alpha mode AND operation not defined / implemented");
674 return; //no-operation
676 else if(aDrawMode&CGraphicsContext::EOr)
679 // RDebug::Printf("Premultiplied alpha mode OR operation not defined / implemented");
681 return; //no-operation
685 TRgb CDrawThirtyTwoBppBitmapAlphaPM::RgbColor(TUint32 aColor) const
687 return TRgb::_Color16MAP(aColor);
690 TUint32 CDrawThirtyTwoBppBitmapAlphaPM::Color(const TRgb& aColor)
692 return aColor._Color16MAP();
695 TInt CDrawThirtyTwoBppBitmapAlphaPM::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
696 TUint32 aOutlinePenColor, TUint32 aShadowColor,
697 TUint32 aFillColor, const TUint8* aDataBuffer)
700 TUint32* pixelPtr = PixelAddress(aX,aY);
701 const TInt pixelPtrInc = PixelAddressIncrement();
702 const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
703 TInt blendedRedColor;
704 TInt blendedGreenColor;
705 TInt blendedBlueColor;
710 //Get red color. Equivalent to TRgb::Red()
711 const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16;
712 const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16;
713 const TInt redFillColor = (aFillColor & 0xff0000) >> 16;
715 //Get green color. Equivalent to TRgb::Green()
716 const TInt greenOutlinePenColor = (aOutlinePenColor & 0xff00) >> 8;
717 const TInt greenShadowColor = (aShadowColor & 0xff00) >> 8;
718 const TInt greenFillColor = (aFillColor & 0xff00) >> 8;
720 //Get blue color. Equivalent to TRgb::Blue()
721 const TInt blueOutlinePenColor = aOutlinePenColor & 0xff;
722 const TInt blueShadowColor = aShadowColor & 0xff;
723 const TInt blueFillColor = aFillColor & 0xff;
725 //Get alpha color. Equivalent to TRgb::Alpha()
726 const TInt alphaOutlinePenColor = aOutlinePenColor >> 24;
727 const TInt alphaShadowColor = aShadowColor >> 24;
728 const TInt alphaFillColor = aFillColor >> 24;
730 // Calculate PMA values for aFillColor & aOutlinePenColor that we can use for fast blending in the simple cases
731 // Don't pre calculate PMA version of aShadowColor as it is presumed not to be used enough to make this worthwhile
732 const TUint32 pmaFillColor = NonPMA2PMAPixel(aFillColor);
733 const TUint32 pmaOutlineColor = NonPMA2PMAPixel(aOutlinePenColor);
735 while (aDataBuffer < dataBufferPtrLimit)
737 index = *aDataBuffer++;
738 if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
741 //No drawing required
743 else if (255 == FourColorBlendLookup[index][KFillColorIndex])
745 //Use fill colour to draw
746 finalColor = pmaFillColor;
747 PMAInplaceBlend(*pixelPtr, finalColor);
749 else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
751 //Use outline colour to draw
752 finalColor = pmaOutlineColor;
753 PMAInplaceBlend(*pixelPtr, finalColor);
755 else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
757 //Use shadow colour to draw
758 finalColor = NonPMA2PMAPixel(aShadowColor);
759 PMAInplaceBlend(*pixelPtr, finalColor);
763 blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor +
764 redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
765 redFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
767 blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor +
768 greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
769 greenFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
771 blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor +
772 blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
773 blueFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
775 blendedAlpha = (alphaOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
776 alphaShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
777 alphaFillColor * FourColorBlendLookup[index][KFillColorIndex]) >> 8;
779 finalColor = (blendedAlpha << 24) | (blendedRedColor << 16) | (blendedGreenColor << 8 )| (blendedBlueColor);
780 PMAInplaceBlend(*pixelPtr, finalColor);
782 pixelPtr += pixelPtrInc;