graphicsdeviceinterface/screendriver/sbit/BMDRAW32A.CPP
changeset 45 36b2e23a8629
parent 0 5d03bc08d59c
equal deleted inserted replaced
36:01a6848ebfd7 45:36b2e23a8629
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    12 //
    12 //
    13 // Description:
    13 // Description:
    14 //
    14 //
    15 
    15 
    16 #include "BMDRAW.H"
    16 #include "BMDRAW.H"
       
    17 #include <graphics/lookuptable.h>
       
    18 #include <graphics/blendingalgorithms.h>
    17 
    19 
    18 /**
    20 /**
    19 Performs a blend based on the PD method, with 2* 16 bit in one 32 bit operation optimisation.
    21 Performs a blend based on the PD method, with 2* 16 bit in one 32 bit operation optimisation.
    20 Note that this method assumes both input s are NOT alpha pre multiplied, but the output IS pre multiplied.
    22 Note that this method assumes both input s are NOT alpha pre multiplied, but the output IS pre multiplied.
    21 The mechanism of this method is non-standard and non-intuitive, and is being addressed in 9.3 
    23 The mechanism of this method is non-standard and non-intuitive, and is being addressed in 9.3 
    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 	}