javauis/lcdui_akn/lcdgr/src/fbslcdgraphics.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 14:23:59 +0300
branchRCL_3
changeset 83 26b2b12093af
parent 19 04becd199f91
permissions -rw-r--r--
Revision: v2.2.17 Kit: 201041

/*
* Copyright (c) 2005 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:
*
*/

#include <fbs.h>
#include "fbslcdgraphics.h"
#include <lcdgdrv.h>

#include "DebugArg.h"

#ifdef _LCDGDRV_FBSBITMAP_SUPPORT_


/**
 * Copy a region of a bitmap - used when creating immutable images from mutable ones, or when creating
 * transformed immutable images from other immutable images.
 */
TInt TFbsLcdGraphics::CopyRegion
(
    CLcdGraphicsDriver& aDriver,
    CFbsBitmap* aDstColorBitmap,
    CFbsBitmap* aDstAlphaBitmap,
    TTransparency aDstTransparency,
    CFbsBitmap* aSrcColorBitmap,
    CFbsBitmap* aSrcAlphaBitmap,
    TTransparency aSrcTransparency,
    const TDrawRegion& aRegion,
    const TRect& aClipRect
)
{
    TAcceleratedBitmapSpec dstColorSpec(aDstColorBitmap);
    TAcceleratedBitmapSpec dstAlphaSpec;
    TAcceleratedBitmapSpec srcColorSpec(aSrcColorBitmap);
    TAcceleratedBitmapSpec srcAlphaSpec;
    TAcceleratedBitmapInfo dstColor;
    TAcceleratedBitmapInfo dstAlpha;
    TAcceleratedBitmapInfo srcColor;
    TAcceleratedBitmapInfo srcAlpha;
    TAcceleratedBitmapInfo* dstAlphaPtr = NULL;
    TAcceleratedBitmapInfo* srcAlphaPtr = NULL;
    TBitmapLockCount count;
    TInt err;

    if (aDstAlphaBitmap)
    {
        new(&dstAlphaSpec) TAcceleratedBitmapSpec(aDstAlphaBitmap);
    }

    if (aSrcAlphaBitmap)
    {
        new(&srcAlphaSpec) TAcceleratedBitmapSpec(aSrcAlphaBitmap);
    }

    //
    // Lock and copy color bitmaps.
    //
    dstColorSpec.Lock(count);
    srcColorSpec.Lock(count);

    if (aDstAlphaBitmap)
    {
        dstAlphaSpec.Lock(count);
    }

    if (aSrcAlphaBitmap)
    {
        srcAlphaSpec.Lock(count);
    }

    dstColorSpec.GetInfo(dstColor);
    srcColorSpec.GetInfo(srcColor);

    if (aDstAlphaBitmap)
    {
        dstAlphaSpec.GetInfo(dstAlpha);
        dstAlphaPtr = &dstAlpha;
    }

    if (aSrcAlphaBitmap)
    {
        srcAlphaSpec.GetInfo(srcAlpha);
        srcAlphaPtr = &srcAlpha;
    }

    TTransformType transform = (TTransformType)aRegion.iTransform;
    TAnchor anchor = (TAnchor)aRegion.iAnchor;

    TRect srcRect(aRegion.iSrcRect);
    TRect clipRect(dstColor.iSize);
    clipRect.Intersection(aClipRect);

    //
    // Compute destination rectangle with anchor point at aRegion.iDstPoint.
    //
    // Destination rectangle need not lie within destination image.
    //
    TRect dstRect = CalcDstRect(aRegion.iDstPoint, srcRect.Size(), transform, anchor);

    err = aDriver.CopyRegion(
              &dstColor,
              dstAlphaPtr,
              aDstTransparency,
              dstRect,
              &srcColor,
              srcAlphaPtr,
              aSrcTransparency,
              srcRect,
              transform,
              clipRect
          );

    if (aSrcAlphaBitmap)
    {
        srcAlphaSpec.Unlock(count);
    }
    if (aDstAlphaBitmap)
    {
        dstAlphaSpec.Unlock(count);
    }

    srcColorSpec.Unlock(count);
    dstColorSpec.Unlock(count);

    return err;
}

TInt TFbsLcdGraphics::GetPixels
(
    CLcdGraphicsDriver& aDriver,
    CFbsBitmap*     aSrcColorBitmap,
    CFbsBitmap*     aSrcAlphaBitmap,
    TTransparency   aSrcTransparency,
    const TRect&    aSrcRect,
    TUint32*        aARGB32Pixels,
    TInt            DEBUG_ARG(aLength),
    TInt            aOffset,
    TInt            aLinePitch,
    const TSize&    aSize
)
{
    ASSERT((aOffset >= 0) && (aOffset < aLength));
    ASSERT((aOffset + aLinePitch*(aSize.iHeight-1) + aSize.iWidth - 1) >= 0);
    ASSERT((aOffset + aLinePitch*(aSize.iHeight-1) + aSize.iWidth - 1) < aLength);

    TAcceleratedBitmapSpec srcColorSpec(aSrcColorBitmap);
    TAcceleratedBitmapSpec srcAlphaSpec;
    if (aSrcAlphaBitmap)
    {
        new(&srcAlphaSpec) TAcceleratedBitmapSpec(aSrcAlphaBitmap);
    }

    TAcceleratedBitmapInfo dstColor;
    TAcceleratedBitmapInfo srcColor;
    TAcceleratedBitmapInfo srcAlpha;
    TBitmapLockCount       count;
    TAcceleratedBitmapInfo* srcAlphaPtr = NULL;

    TTransformType transform = ETransNone;
    TUint8* address = (TUint8*)(aARGB32Pixels) + aOffset*sizeof(TUint32);
    if (aLinePitch < 0)
    {
        //
        // compute address of first row of image.
        //
        address += aLinePitch * (aSize.iHeight - 1) * sizeof(TUint32);

        //
        // use vertical reflection blitter.
        //
        transform = ETransMirrorRot180;

        //
        // correct sign of linePitch
        //
        aLinePitch = - aLinePitch;
    }

    CLcdGraphicsDriver::TDriverInfo info;
    aDriver.GetDriverInfo(info);

    dstColor.iAddress     = address;
    dstColor.iDisplayMode = info.iARGB8888Mode;
    dstColor.iPixelShift  = 5;                          // or 32?
    dstColor.iLinePitch   = aLinePitch*sizeof(TUint32); // bytes
    dstColor.iSize        = aSize;                      //
    dstColor.iPhysicalAddress = NULL;                   // software bitmap

    srcColorSpec.Lock(count);
    srcColorSpec.GetInfo(srcColor);
    if (aSrcAlphaBitmap)
    {
        srcAlphaSpec.Lock(count);
        srcAlphaSpec.GetInfo(srcAlpha);
        srcAlphaPtr = &srcAlpha;
    }

    TRect dstRect(aSize);
    TRect clipRect(aSize);

    TInt err = aDriver.CopyRegion
               (
                   &dstColor,
                   NULL,
                   ETransparencyAlphaChannel,
                   dstRect,
                   &srcColor,
                   srcAlphaPtr,
                   aSrcTransparency,
                   aSrcRect,
                   transform,
                   clipRect
               );

    if (aSrcAlphaBitmap)
    {
        srcAlphaSpec.Unlock(count);
    }
    srcColorSpec.Unlock(count);

    return err;
}

/**
 *
 */
TInt TFbsLcdGraphics::SetPixels
(
    CLcdGraphicsDriver& aDriver,
    CFbsBitmap*     aDstColorBitmap,
    CFbsBitmap*     aDstAlphaBitmap,
    TTransparency   aDstTransparency,
    const TRect&    aDstRect,
    const TUint32*  aARGB32Pixels,
    TInt            DEBUG_ARG(aLength),
    TInt            aOffset,
    TInt            aLinePitch,
    const TSize&    aSize,
    TBool           aAlpha
)
{
    ASSERT((aOffset >= 0) && (aOffset < aLength));
    ASSERT((aOffset + aLinePitch*(aSize.iHeight-1) + aSize.iWidth - 1) >= 0);
    ASSERT((aOffset + aLinePitch*(aSize.iHeight-1) + aSize.iWidth - 1) < aLength);

    TAcceleratedBitmapSpec dstColorSpec(aDstColorBitmap);
    TAcceleratedBitmapSpec dstAlphaSpec;
    if (aDstAlphaBitmap)
    {
        new(&dstAlphaSpec) TAcceleratedBitmapSpec(aDstAlphaBitmap);
    }

    TAcceleratedBitmapInfo srcColor;
    TAcceleratedBitmapInfo dstColor;
    TAcceleratedBitmapInfo dstAlpha;
    TAcceleratedBitmapInfo* dstAlphaPtr = NULL;
    TBitmapLockCount count;


    TTransformType transform = ETransNone;
    TUint8* address = (TUint8*)(aARGB32Pixels) + aOffset*sizeof(TUint32);
    if (aLinePitch < 0)
    {
        //
        // compute address of first row of image.
        //
        address += aLinePitch * (aSize.iHeight - 1) * sizeof(TUint32);

        //
        // use vertical reflection blitter.
        //
        transform = ETransMirrorRot180;

        //
        // correct sign of linePitch
        //
        aLinePitch = - aLinePitch;
    }

    CLcdGraphicsDriver::TDriverInfo info;
    aDriver.GetDriverInfo(info);

    srcColor.iAddress     = address;                    // address of top-left pixel in src
    srcColor.iDisplayMode = info.iARGB8888Mode;         // how driver recognises ARGB8888 pixels
    srcColor.iPixelShift  = 5;                          //
    srcColor.iLinePitch   = aLinePitch*sizeof(TUint32); // bytes
    srcColor.iSize        = aSize;                      //
    srcColor.iPhysicalAddress = NULL;                   // software bitmap

    TTransparency srcTransparency = (aAlpha ? ETransparencyAlphaChannel : ETransparencyIgnoreChannel);

    dstColorSpec.Lock(count);
    dstColorSpec.GetInfo(dstColor);
    if (aDstAlphaBitmap)
    {
        dstAlphaSpec.Lock(count);
        dstAlphaSpec.GetInfo(dstAlpha);
        dstAlphaPtr = &dstAlpha;
    }

    TRect srcRect(aSize);
    TRect clipRect(dstColor.iSize);

    TInt err = aDriver.CopyRegion
               (
                   &dstColor,
                   dstAlphaPtr,
                   aDstTransparency,
                   aDstRect,
                   &srcColor,
                   NULL,
                   srcTransparency,
                   srcRect,
                   transform,
                   clipRect
               );

    if (aDstAlphaBitmap)
    {
        dstAlphaSpec.Unlock(count);
    }
    dstColorSpec.Unlock(count);

    return err;
}


TBool TFbsLcdGraphics::DetectCollision
(
    CLcdGraphicsDriver& aDriver,

    CFbsBitmap*         aMask1,
    TTransparency       aTransparency1,
    const TSize&        aSize1,
    const TRect&        aRect1,
    TInt                aTransform1,
    const TPoint&       aPoint1,

    CFbsBitmap*         aMask2,
    TTransparency       aTransparency2,
    const TSize&        aSize2,
    const TRect&        aRect2,
    TInt                aTransform2,
    const TPoint&       aPoint2
)
{
    TAcceleratedBitmapSpec bitmapSpec1;
    TAcceleratedBitmapInfo bitmapInfo1;
    TAcceleratedBitmapInfo* bitmapPtr1 = NULL;
    TAcceleratedBitmapSpec bitmapSpec2;
    TAcceleratedBitmapInfo bitmapInfo2;
    TAcceleratedBitmapInfo* bitmapPtr2 = NULL;

    TBitmapLockCount count;

    if (aMask1)
    {
        bitmapSpec1 = TAcceleratedBitmapSpec(aMask1);
    }

    if (aMask2)
    {
        bitmapSpec2 = TAcceleratedBitmapSpec(aMask2);
    }

    if (aMask1)
    {
        bitmapSpec1.Lock(count);
        bitmapSpec1.GetInfo(bitmapInfo1);
        bitmapPtr1 = &bitmapInfo1;
    }

    if (aMask2)
    {
        bitmapSpec2.Lock(count);
        bitmapSpec2.GetInfo(bitmapInfo2);
        bitmapPtr2 = &bitmapInfo2;
    }

    TBool collision =  aDriver.DetectCollision(
                           bitmapPtr1,
                           aTransparency1,
                           aSize1,
                           aRect1,
                           aTransform1,
                           aPoint1,

                           bitmapPtr2,
                           aTransparency2,
                           aSize2,
                           aRect2,
                           aTransform2,
                           aPoint2
                       );

    if (aMask2)
    {
        bitmapSpec2.Unlock(count);
    }

    if (aMask1)
    {
        bitmapSpec1.Unlock(count);
    }

    return collision;
}
#endif

/**
 * Compute destination rectangle of rectangle of size aSrcSize, transformed by aSrcTransform
 * and then positioned with a reference point specified by aSrcAnchor at aDstPoint.
 */
TRect CalcDstRect(const TPoint& aDstPoint, const TSize& aSrcSize, TTransformType aSrcTransform, TAnchor aSrcAnchor)
{
    TPoint point = aDstPoint;
    TSize  size  = aSrcSize;

    if (aSrcTransform & EReflectDiag)
    {
        TInt tmp = size.iWidth;
        size.iWidth  = size.iHeight;
        size.iHeight = tmp;
    }

    if (aSrcAnchor & EAnchorHCenter)
    {
        point.iX -= size.iWidth/2;
    }
    else if (aSrcAnchor & EAnchorRight)
    {
        point.iX -= size.iWidth;
    }

    if (aSrcAnchor & EAnchorVCenter)
    {
        point.iY -= size.iHeight/2;
    }
    else if (aSrcAnchor & EAnchorBottom)
    {
        point.iY -= size.iHeight;
    }

    return TRect(point, size);
}