javauis/lcdui_akn/javalcdui/src.nokialcdui/TMIDFormatConverter.cpp
branchRCL_3
changeset 19 04becd199f91
--- /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 <fbs.h>
+
+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;
+}