diff -r f5050f1da672 -r 04becd199f91 javauis/lcdui_akn/javalcdui/src.nokialcdui/TMIDFormatConverter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/lcdui_akn/javalcdui/src.nokialcdui/TMIDFormatConverter.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,294 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Abstract base class for format converters. +* +*/ + + + +// INCLUDE FILES +#include "TMIDFormatConverter.h" +#include "TMIDGray1.h" +#include + +namespace +{ +const TInt KAnchorHCenter = 1; +const TInt KAnchorVCenter = 2; +const TInt KAnchorRight = 8; +const TInt KAnchorBottom = 32; +const TInt KScanLengthOffset = 31; +const TInt KScanLengthDivider = 32; +} + +TMIDFormatConverter::TMIDFormatConverter() +{ + iTransformer = TMIDTransformer(); + iBitmapRect = TRect(); + iOffset = 0; + iScanlength = 0; + iAlphaBitmap = NULL; + iAlphaMode = ENone; + iTransparency = ETrue; +} + +void TMIDFormatConverter::InitializeL(const TMIDBitmapParameters& aParameters) +{ + iOffset = aParameters.iOffset; + iScanlength = aParameters.iScanLength; + iAlphaBitmap = aParameters.iAlpha; + iAlphaMode = aParameters.iAlphaMode; + iTransparency = aParameters.iTransparency; + + switch (iAlphaMode) + { + case EGray2: + { + iAlphaScanLength = ((aParameters.iWidth + KScanLengthOffset) / + KScanLengthDivider); + + break; + } + default: + { + if (iAlphaBitmap) + { + iAlphaScanLength = aParameters.iBitmap->ScanLineLength( + aParameters.iWidth, iAlphaMode); + } + } + } + + TInt lastPixel = iScanlength * (aParameters.iHeight - 1) + + aParameters.iWidth - 1 + iOffset; + + // checking that bitmap is big enough + if (iOffset < 0 || + !CheckSize(aParameters.iPixelsSize, lastPixel)) + { + // out of bounds + User::Leave(KErrArrayIndexOutOfBoundsException); + } + + // checking alpha size + if (iAlphaBitmap) + { + if (((iAlphaMode == EGray256) && + (aParameters.iAlphaSize < + (aParameters.iHeight * aParameters.iWidth + iOffset))) || + ((iAlphaMode == EGray2) && + (aParameters.iAlphaSize < + (aParameters.iHeight * (aParameters.iWidth >> KMIDShift3Bits) + + iOffset))) || + ((iAlphaMode != EGray256) && (iAlphaMode != EGray2) && + (!CheckSize(aParameters.iAlphaSize, lastPixel)))) + { + // out of bounds + User::Leave(KErrArrayIndexOutOfBoundsException); + } + } + + + iBitmapRect = TRect(aParameters.iX, aParameters.iY, + aParameters.iX + aParameters.iWidth, + aParameters.iY + aParameters.iHeight); + + // initializing transformer, this will only rotate + iTransformer.Transform(iBitmapRect, aParameters.iManipulation); + + // calculating new position from anchor point + if (aParameters.iAnchor != 0) + { + if (aParameters.iAnchor & KAnchorRight) + { + iBitmapRect.Move(-iBitmapRect.Width(), 0); + } + if (aParameters.iAnchor & KAnchorBottom) + { + iBitmapRect.Move(0, -iBitmapRect.Height()); + } + if (aParameters.iAnchor & KAnchorHCenter) + { + iBitmapRect.Move(-(iBitmapRect.Width() >> 1), 0); + } + if (aParameters.iAnchor & KAnchorVCenter) + { + iBitmapRect.Move(0, -(iBitmapRect.Height() >> 1)); + } + } + + + // second phase of initialization, this will do actual initalization of directions + // for both flip and rotate. Movement value is for changing starting position if out + // of clipping rect. + TPoint move(0, 0); + if (iBitmapRect.iTl.iX < aParameters.iClipRect.iTl.iX) + { + move.iX = aParameters.iClipRect.iTl.iX - iBitmapRect.iTl.iX; + } + if (iBitmapRect.iTl.iY < aParameters.iClipRect.iTl.iY) + { + move.iY = aParameters.iClipRect.iTl.iY - iBitmapRect.iTl.iY; + } + + // This will rotate and flip bitmap, returns error code if manipulation is + // invalid + User::LeaveIfError(iTransformer.Transform(move)); + + // calculating possible new size after clipping + iBitmapRect.Intersection(aParameters.iClipRect); + if (iBitmapRect.IsEmpty()) + { + // we are not in clipping rect, cancelling the drawing + return; + } + + // iTransformers moves are two dimensional moves with following combinations + // x-move y-move + // (1, 0) (0, 1) Default (no rotations or flips) + // (1, 0) (0,-1) + // (-1,0) (0, 1) + // (-1,0) (0,-1) + // (0, 1) (1, 0) + // (0, 1) (-1,0) + // (0,-1) (1, 0) + // (0,-1) (-1,0) + + // So precalculating moves + + // going right or left when advancing y + // x(y) y(x) + //(1) (1) -scan * (height - 1) + 1 + //(1) (-1) -scan * (height - 1) - 1 + //(-1) (1) scan * (height - 1) + 1 + //(-1) (-1) scan * (height - 1) - 1 + if (iTransformer.iYMove.iX != 0) + { + iTransformer.iYMove.iX += (-(iTransformer.iXMove.iY) * iScanlength) * + (iBitmapRect.Width() - 1); + } + + // going up or down when advancing x + iTransformer.iXMove.iY *= iScanlength; + + // going up or down (default) when advancing y + // x y + //(1) (1) scan - width + 1 + //(-1) (1) scan + width - 1 + //(1) (-1) -scan - width + 1 + //(-1) (-1) -scan + width - 1 + iTransformer.iYMove.iY = iTransformer.iYMove.iY * iScanlength - + (iTransformer.iXMove.iX * iBitmapRect.Width()) + iTransformer.iXMove.iX; + + // combine x & y to one value + iTransformer.iXMove.iX += iTransformer.iXMove.iY; + iTransformer.iYMove.iX += iTransformer.iYMove.iY; +} + + +void TMIDFormatConverter::GetPixelWithAlpha(TMIDInternalARGB& aResult) const +{ + GetPixel(aResult); + switch (iAlphaMode) + { + case(EGray256): + { + TInt line = iOffset / iScanlength; + TInt column = iOffset % iScanlength; + aResult.iA = + ((TUint8*)iAlphaBitmap)[ line * iAlphaScanLength + column ]; // CSI: 2 Wrong index means implementation error # + break; + } + case(EGray2): + { + TInt line = iOffset / iScanlength; + TInt column = iOffset % iScanlength; + TInt word = line * iAlphaScanLength + (column >> KMIDShift5Bits); + aResult.iA = (((((TUint32*)iAlphaBitmap)[ word ] >> // CSI: 2 Wrong index means implementation error # + (column % KScanLengthDivider)) & 1) * KAlphaFullOpaque); + + break; + } + default: + { + aResult.iA = GetAlpha(); + } + } +} + +void TMIDFormatConverter::PlotPixelWithAlpha(const TMIDInternalARGB& aInternal) +{ + PlotPixel(aInternal); + + // modifying alpha channel + if (iAlphaBitmap) + { + switch (iAlphaMode) + { + case(EGray256): + { + TInt line = iOffset / iScanlength; + TInt column = iOffset % iScanlength; + ((TUint8*)iAlphaBitmap)[ line * iAlphaScanLength + column ] = // CSI: 2 Wrong index means implementation error # + aInternal.iA; + break; + } + case(EGray2): + { + TInt line = iOffset / iScanlength; + TInt column = iOffset % iScanlength; + TInt word = line * iAlphaScanLength + (column >> KMIDShift5Bits); + if ((aInternal.iR + aInternal.iG + aInternal.iB) < + KWhiteBlackSumRGBMidValue) + { + iAlphaBitmap[ word ] = (TUint32)(iAlphaBitmap[ word ] | // CSI: 2 Wrong offset means implementation error # + KBits32[ column % KScanLengthDivider ]); // CSI: 2 Wrong index means implementation error # + } + else + { + iAlphaBitmap[ word ] = (TUint32)(iAlphaBitmap[ word ] & // CSI: 2 Wrong offset means implementation error # + ~KBits32[ column % KScanLengthDivider ]); // CSI: 2 Wrong index means implementation error # + } + } + default: + { + // otherwise we have same format as normal bitmap + // getting real bitmap from converter + TUint32* tempBitmap = Bitmap(); + SetBitmap(iAlphaBitmap); + + // It must be either white or black + TMIDInternalARGB alphaIn; + if (aInternal.iA == KAlphaFullOpaque) + { + alphaIn = KOpaque; + } + PlotPixel(alphaIn); + + // reverting to original bitmap + SetBitmap(tempBitmap); + } + } + } +} + +TBool TMIDFormatConverter::IsAlpha() +{ + + if (iAlphaBitmap) + { + return ETrue; + } + return EFalse; +}