35 If we multiply by 1.1 then we get 0.0 .. 9.9. |
37 If we multiply by 1.1 then we get 0.0 .. 9.9. |
36 And finally add a 0.5 rounding to the result. |
38 And finally add a 0.5 rounding to the result. |
37 I do this multiply after the CSrc*MulSrc, while I still have a 16bit intermediate result. |
39 I do this multiply after the CSrc*MulSrc, while I still have a 16bit intermediate result. |
38 It is possible to generate a faster, less accurate result by exhaustively finding |
40 It is possible to generate a faster, less accurate result by exhaustively finding |
39 the highest value that can be added instead of rb = rb+((rb>>8)&0x00ff00ff)+0x00800080; without causing an overflow. |
41 the highest value that can be added instead of rb = rb+((rb>>8)&0x00ff00ff)+0x00800080; without causing an overflow. |
|
42 @param aBeneath non-premultiplied color with alpha of the destination |
|
43 @param aSrcColor non-premultiplied color with alpha of the source |
|
44 @param aMaskBuffer mask |
|
45 @return pre multiplied color resulting from the blending operation |
40 */ |
46 */ |
41 FORCEINLINE TUint32 OptimizedBlend32A(TUint32 aBeneath,TUint32 aSrcColor,TUint8 aMaskBuffer) |
47 FORCEINLINE TUint32 OptimizedBlend32A(TUint32 aBeneath,TUint32 aSrcColor,TUint8 aMaskBuffer) |
42 { |
48 { |
43 if(aMaskBuffer) |
49 if(aMaskBuffer) |
44 { |
50 { |
634 const TInt pixelPtrInc = PixelAddressIncrement(); |
640 const TInt pixelPtrInc = PixelAddressIncrement(); |
635 const TUint8* dataBufferPtrLimit = aDataBuffer + aLength; |
641 const TUint8* dataBufferPtrLimit = aDataBuffer + aLength; |
636 TInt blendedRedColor; |
642 TInt blendedRedColor; |
637 TInt blendedGreenColor; |
643 TInt blendedGreenColor; |
638 TInt blendedBlueColor; |
644 TInt blendedBlueColor; |
|
645 TInt blendedAlpha; |
639 TUint8 index = 0; |
646 TUint8 index = 0; |
640 TUint32 finalColor; |
647 TUint32 finalColor; |
641 |
648 const TUint16* normTable = PtrTo16BitNormalisationTable(); |
|
649 |
642 //Get red color. Equivalent to TRgb::Red() |
650 //Get red color. Equivalent to TRgb::Red() |
643 const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16; |
651 const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16; |
644 const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16; |
652 const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16; |
645 const TInt redFillColor = (aFillColor & 0xff0000) >> 16; |
653 const TInt redFillColor = (aFillColor & 0xff0000) >> 16; |
646 |
654 |
651 |
659 |
652 //Get blue color. Equivalent to TRgb::Blue() |
660 //Get blue color. Equivalent to TRgb::Blue() |
653 const TInt blueOutlinePenColor = aOutlinePenColor & 0xff; |
661 const TInt blueOutlinePenColor = aOutlinePenColor & 0xff; |
654 const TInt blueShadowColor = aShadowColor & 0xff; |
662 const TInt blueShadowColor = aShadowColor & 0xff; |
655 const TInt blueFillColor = aFillColor & 0xff; |
663 const TInt blueFillColor = aFillColor & 0xff; |
656 const TInt alpha = aOutlinePenColor >> 24; |
664 |
|
665 //Get alpha color. Equivalent to TRgb::Alpha() |
|
666 const TInt alphaOutlinePenColor = aOutlinePenColor >> 24; |
|
667 const TInt alphaShadowColor = aShadowColor >> 24; |
|
668 const TInt alphaFillColor = aFillColor >> 24; |
657 |
669 |
658 while (aDataBuffer < dataBufferPtrLimit) |
670 while (aDataBuffer < dataBufferPtrLimit) |
659 { |
671 { |
660 index = *aDataBuffer++; |
672 index = *aDataBuffer++; |
661 if(255 == FourColorBlendLookup[index][KBackgroundColorIndex]) |
673 if(255 == FourColorBlendLookup[index][KBackgroundColorIndex]) |
662 { |
674 { |
663 //background colour |
675 //background colour |
664 //No drawing required so move on to next pixel. |
676 //No drawing required |
665 pixelPtr += pixelPtrInc; |
|
666 continue; |
|
667 } |
677 } |
668 else if (255 == FourColorBlendLookup[index][KFillColorIndex]) |
678 else if (255 == FourColorBlendLookup[index][KFillColorIndex]) |
669 { |
679 { |
670 //Use fill colour to draw |
680 //Use fill colour to draw |
671 finalColor = aFillColor; |
681 finalColor = OptimizedBlend32A(*pixelPtr, aFillColor, alphaFillColor); |
|
682 *pixelPtr = PMA2NonPMAPixel(finalColor, normTable); |
672 } |
683 } |
673 else if (255 == FourColorBlendLookup[index][KShadowColorIndex]) |
684 else if (255 == FourColorBlendLookup[index][KShadowColorIndex]) |
674 { |
685 { |
675 //Use shadow colour to draw |
686 //Use shadow colour to draw |
676 finalColor = aShadowColor; |
687 finalColor = OptimizedBlend32A(*pixelPtr, aShadowColor, alphaShadowColor); |
|
688 *pixelPtr = PMA2NonPMAPixel(finalColor, normTable); |
677 } |
689 } |
678 else if (255 == FourColorBlendLookup[index][KOutlineColorIndex]) |
690 else if (255 == FourColorBlendLookup[index][KOutlineColorIndex]) |
679 { |
691 { |
680 //Use outline colour to draw |
692 //Use outline colour to draw |
681 finalColor = aOutlinePenColor; |
693 finalColor = OptimizedBlend32A(*pixelPtr, aOutlinePenColor, alphaOutlinePenColor); |
|
694 *pixelPtr = PMA2NonPMAPixel(finalColor, normTable); |
682 } |
695 } |
683 else |
696 else |
684 { |
697 { |
685 const TUint32 backgroundColor = *pixelPtr; |
698 blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor + |
686 |
699 redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor + |
687 blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + |
700 redFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16; |
688 redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] + |
701 |
689 redFillColor * FourColorBlendLookup[index][KFillColorIndex] + |
702 blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor + |
690 ((backgroundColor & 0xff0000) >> 16) * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8; |
703 greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor + |
691 |
704 greenFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16; |
692 blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + |
705 |
693 greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] + |
706 blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor + |
694 greenFillColor * FourColorBlendLookup[index][KFillColorIndex] + |
707 blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor + |
695 ((backgroundColor & 0xff00) >> 8) * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8; |
708 blueFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16; |
696 |
709 |
697 blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + |
710 blendedAlpha = (alphaOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + |
698 blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] + |
711 alphaShadowColor * FourColorBlendLookup[index][KShadowColorIndex] + |
699 blueFillColor * FourColorBlendLookup[index][KFillColorIndex] + |
712 alphaFillColor * FourColorBlendLookup[index][KFillColorIndex]) >> 8; |
700 (backgroundColor & 0xff) * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8; |
713 |
701 |
714 // The blended colours have been alpha multiplied, hence the resulting colour is 16MAP |
702 finalColor = (blendedRedColor << 16) | (blendedGreenColor << 8) | blendedBlueColor | 0xff000000; |
715 // Before doing the OptimizedBlend with the destination, note the following |
703 } |
716 // - The source alpha is set as fully opaque so that the blend is just with the mask |
704 *pixelPtr = OptimizedBlend32A(*pixelPtr, finalColor, alpha); |
717 // - Input parameters for OptimizedBlend are NON-PRE, hence conversion from PRE to NON-PRE beforehand |
|
718 // - output parameter for OptimizedBlend is PRE, hence conversion from PRE to NON-PRE afterwards |
|
719 finalColor = PMA2NonPMAPixel((blendedAlpha << 24) | (blendedRedColor << 16) | (blendedGreenColor << 8) | blendedBlueColor, normTable); |
|
720 finalColor = OptimizedBlend32A(*pixelPtr, finalColor | 0xff000000, blendedAlpha); |
|
721 *pixelPtr = PMA2NonPMAPixel(finalColor, normTable); |
|
722 } |
705 pixelPtr += pixelPtrInc; |
723 pixelPtr += pixelPtrInc; |
706 } |
724 } |
707 return KErrNone; |
725 return KErrNone; |
708 } |
726 } |