javauis/lcdui_akn/javalcdui/src.nokialcdui/TMIDFormatConverter.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Abstract base class for format converters.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //  INCLUDE FILES
       
    21 #include "TMIDFormatConverter.h"
       
    22 #include "TMIDGray1.h"
       
    23 #include <fbs.h>
       
    24 
       
    25 namespace
       
    26 {
       
    27 const TInt KAnchorHCenter = 1;
       
    28 const TInt KAnchorVCenter = 2;
       
    29 const TInt KAnchorRight = 8;
       
    30 const TInt KAnchorBottom = 32;
       
    31 const TInt KScanLengthOffset = 31;
       
    32 const TInt KScanLengthDivider = 32;
       
    33 }
       
    34 
       
    35 TMIDFormatConverter::TMIDFormatConverter()
       
    36 {
       
    37     iTransformer = TMIDTransformer();
       
    38     iBitmapRect = TRect();
       
    39     iOffset = 0;
       
    40     iScanlength = 0;
       
    41     iAlphaBitmap = NULL;
       
    42     iAlphaMode = ENone;
       
    43     iTransparency = ETrue;
       
    44 }
       
    45 
       
    46 void TMIDFormatConverter::InitializeL(const TMIDBitmapParameters& aParameters)
       
    47 {
       
    48     iOffset = aParameters.iOffset;
       
    49     iScanlength = aParameters.iScanLength;
       
    50     iAlphaBitmap = aParameters.iAlpha;
       
    51     iAlphaMode = aParameters.iAlphaMode;
       
    52     iTransparency = aParameters.iTransparency;
       
    53 
       
    54     switch (iAlphaMode)
       
    55     {
       
    56     case EGray2:
       
    57     {
       
    58         iAlphaScanLength = ((aParameters.iWidth + KScanLengthOffset) /
       
    59                             KScanLengthDivider);
       
    60 
       
    61         break;
       
    62     }
       
    63     default:
       
    64     {
       
    65         if (iAlphaBitmap)
       
    66         {
       
    67             iAlphaScanLength = aParameters.iBitmap->ScanLineLength(
       
    68                                    aParameters.iWidth, iAlphaMode);
       
    69         }
       
    70     }
       
    71     }
       
    72 
       
    73     TInt lastPixel = iScanlength * (aParameters.iHeight - 1) +
       
    74                      aParameters.iWidth - 1 + iOffset;
       
    75 
       
    76     // checking that bitmap is big enough
       
    77     if (iOffset < 0 ||
       
    78             !CheckSize(aParameters.iPixelsSize, lastPixel))
       
    79     {
       
    80         // out of bounds
       
    81         User::Leave(KErrArrayIndexOutOfBoundsException);
       
    82     }
       
    83 
       
    84     // checking alpha size
       
    85     if (iAlphaBitmap)
       
    86     {
       
    87         if (((iAlphaMode == EGray256) &&
       
    88                 (aParameters.iAlphaSize <
       
    89                  (aParameters.iHeight * aParameters.iWidth + iOffset))) ||
       
    90                 ((iAlphaMode == EGray2) &&
       
    91                  (aParameters.iAlphaSize <
       
    92                   (aParameters.iHeight * (aParameters.iWidth >> KMIDShift3Bits)
       
    93                    + iOffset))) ||
       
    94                 ((iAlphaMode != EGray256) && (iAlphaMode != EGray2) &&
       
    95                  (!CheckSize(aParameters.iAlphaSize, lastPixel))))
       
    96         {
       
    97             // out of bounds
       
    98             User::Leave(KErrArrayIndexOutOfBoundsException);
       
    99         }
       
   100     }
       
   101 
       
   102 
       
   103     iBitmapRect = TRect(aParameters.iX, aParameters.iY,
       
   104                         aParameters.iX + aParameters.iWidth,
       
   105                         aParameters.iY + aParameters.iHeight);
       
   106 
       
   107     // initializing transformer, this will only rotate
       
   108     iTransformer.Transform(iBitmapRect, aParameters.iManipulation);
       
   109 
       
   110     // calculating new position from anchor point
       
   111     if (aParameters.iAnchor != 0)
       
   112     {
       
   113         if (aParameters.iAnchor & KAnchorRight)
       
   114         {
       
   115             iBitmapRect.Move(-iBitmapRect.Width(), 0);
       
   116         }
       
   117         if (aParameters.iAnchor & KAnchorBottom)
       
   118         {
       
   119             iBitmapRect.Move(0, -iBitmapRect.Height());
       
   120         }
       
   121         if (aParameters.iAnchor & KAnchorHCenter)
       
   122         {
       
   123             iBitmapRect.Move(-(iBitmapRect.Width() >> 1), 0);
       
   124         }
       
   125         if (aParameters.iAnchor & KAnchorVCenter)
       
   126         {
       
   127             iBitmapRect.Move(0, -(iBitmapRect.Height() >> 1));
       
   128         }
       
   129     }
       
   130 
       
   131 
       
   132     // second phase of initialization, this will do actual initalization of directions
       
   133     // for both flip and rotate. Movement value is for changing starting position if out
       
   134     // of clipping rect.
       
   135     TPoint move(0, 0);
       
   136     if (iBitmapRect.iTl.iX < aParameters.iClipRect.iTl.iX)
       
   137     {
       
   138         move.iX = aParameters.iClipRect.iTl.iX - iBitmapRect.iTl.iX;
       
   139     }
       
   140     if (iBitmapRect.iTl.iY < aParameters.iClipRect.iTl.iY)
       
   141     {
       
   142         move.iY = aParameters.iClipRect.iTl.iY - iBitmapRect.iTl.iY;
       
   143     }
       
   144 
       
   145     // This will rotate and flip bitmap, returns error code if manipulation is
       
   146     // invalid
       
   147     User::LeaveIfError(iTransformer.Transform(move));
       
   148 
       
   149     // calculating possible new size after clipping
       
   150     iBitmapRect.Intersection(aParameters.iClipRect);
       
   151     if (iBitmapRect.IsEmpty())
       
   152     {
       
   153         // we are not in clipping rect, cancelling the drawing
       
   154         return;
       
   155     }
       
   156 
       
   157     // iTransformers moves are two dimensional moves with following combinations
       
   158     // x-move y-move
       
   159     // (1, 0) (0, 1) Default (no rotations or flips)
       
   160     // (1, 0) (0,-1)
       
   161     // (-1,0) (0, 1)
       
   162     // (-1,0) (0,-1)
       
   163     // (0, 1) (1, 0)
       
   164     // (0, 1) (-1,0)
       
   165     // (0,-1) (1, 0)
       
   166     // (0,-1) (-1,0)
       
   167 
       
   168     // So precalculating moves
       
   169 
       
   170     // going right or left when advancing y
       
   171     // x(y) y(x)
       
   172     //(1)   (1)  -scan * (height - 1) + 1
       
   173     //(1)   (-1) -scan * (height - 1) - 1
       
   174     //(-1)  (1)   scan * (height - 1) + 1
       
   175     //(-1)  (-1)  scan * (height - 1) - 1
       
   176     if (iTransformer.iYMove.iX != 0)
       
   177     {
       
   178         iTransformer.iYMove.iX += (-(iTransformer.iXMove.iY) * iScanlength) *
       
   179                                   (iBitmapRect.Width() - 1);
       
   180     }
       
   181 
       
   182     // going up or down when advancing x
       
   183     iTransformer.iXMove.iY *= iScanlength;
       
   184 
       
   185     // going up or down (default) when advancing y
       
   186     // x    y
       
   187     //(1)   (1)  scan - width + 1
       
   188     //(-1)  (1)  scan + width - 1
       
   189     //(1)   (-1) -scan - width + 1
       
   190     //(-1)  (-1) -scan + width - 1
       
   191     iTransformer.iYMove.iY = iTransformer.iYMove.iY * iScanlength -
       
   192                              (iTransformer.iXMove.iX * iBitmapRect.Width()) + iTransformer.iXMove.iX;
       
   193 
       
   194     // combine x & y to one value
       
   195     iTransformer.iXMove.iX += iTransformer.iXMove.iY;
       
   196     iTransformer.iYMove.iX += iTransformer.iYMove.iY;
       
   197 }
       
   198 
       
   199 
       
   200 void TMIDFormatConverter::GetPixelWithAlpha(TMIDInternalARGB& aResult) const
       
   201 {
       
   202     GetPixel(aResult);
       
   203     switch (iAlphaMode)
       
   204     {
       
   205     case(EGray256):
       
   206     {
       
   207         TInt line = iOffset / iScanlength;
       
   208         TInt column = iOffset % iScanlength;
       
   209         aResult.iA =
       
   210             ((TUint8*)iAlphaBitmap)[ line * iAlphaScanLength + column ];  // CSI: 2 Wrong index means implementation error #
       
   211         break;
       
   212     }
       
   213     case(EGray2):
       
   214     {
       
   215         TInt line = iOffset / iScanlength;
       
   216         TInt column = iOffset % iScanlength;
       
   217         TInt word = line * iAlphaScanLength + (column >> KMIDShift5Bits);
       
   218         aResult.iA = (((((TUint32*)iAlphaBitmap)[ word ] >>    // CSI: 2 Wrong index means implementation error #
       
   219                         (column % KScanLengthDivider)) & 1) * KAlphaFullOpaque);
       
   220 
       
   221         break;
       
   222     }
       
   223     default:
       
   224     {
       
   225         aResult.iA = GetAlpha();
       
   226     }
       
   227     }
       
   228 }
       
   229 
       
   230 void TMIDFormatConverter::PlotPixelWithAlpha(const TMIDInternalARGB& aInternal)
       
   231 {
       
   232     PlotPixel(aInternal);
       
   233 
       
   234     // modifying alpha channel
       
   235     if (iAlphaBitmap)
       
   236     {
       
   237         switch (iAlphaMode)
       
   238         {
       
   239         case(EGray256):
       
   240         {
       
   241             TInt line = iOffset / iScanlength;
       
   242             TInt column = iOffset % iScanlength;
       
   243             ((TUint8*)iAlphaBitmap)[ line * iAlphaScanLength + column ] =  // CSI: 2 Wrong index means implementation error #
       
   244                 aInternal.iA;
       
   245             break;
       
   246         }
       
   247         case(EGray2):
       
   248         {
       
   249             TInt line = iOffset / iScanlength;
       
   250             TInt column = iOffset % iScanlength;
       
   251             TInt word = line * iAlphaScanLength + (column >> KMIDShift5Bits);
       
   252             if ((aInternal.iR + aInternal.iG + aInternal.iB) <
       
   253                     KWhiteBlackSumRGBMidValue)
       
   254             {
       
   255                 iAlphaBitmap[ word ] = (TUint32)(iAlphaBitmap[ word ] |      // CSI: 2 Wrong offset means implementation error #
       
   256                                                  KBits32[ column % KScanLengthDivider ]);   // CSI: 2 Wrong index means implementation error #
       
   257             }
       
   258             else
       
   259             {
       
   260                 iAlphaBitmap[ word ] = (TUint32)(iAlphaBitmap[ word ] &     // CSI: 2 Wrong offset means implementation error #
       
   261                                                  ~KBits32[ column % KScanLengthDivider ]);   // CSI: 2 Wrong index means implementation error #
       
   262             }
       
   263         }
       
   264         default:
       
   265         {
       
   266             // otherwise we have same format as normal bitmap
       
   267             // getting real bitmap from converter
       
   268             TUint32* tempBitmap = Bitmap();
       
   269             SetBitmap(iAlphaBitmap);
       
   270 
       
   271             // It must be either white or black
       
   272             TMIDInternalARGB alphaIn;
       
   273             if (aInternal.iA == KAlphaFullOpaque)
       
   274             {
       
   275                 alphaIn = KOpaque;
       
   276             }
       
   277             PlotPixel(alphaIn);
       
   278 
       
   279             // reverting to original bitmap
       
   280             SetBitmap(tempBitmap);
       
   281         }
       
   282         }
       
   283     }
       
   284 }
       
   285 
       
   286 TBool TMIDFormatConverter::IsAlpha()
       
   287 {
       
   288 
       
   289     if (iAlphaBitmap)
       
   290     {
       
   291         return ETrue;
       
   292     }
       
   293     return EFalse;
       
   294 }