javauis/lcdui_akn/lcdgd/src/lcd32bpp.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 19 Aug 2010 09:48:13 +0300
branchRCL_3
changeset 60 6c158198356e
parent 19 04becd199f91
permissions -rw-r--r--
Revision: v2.2.9 Kit: 201033

/*
* 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 <e32std.h>
#include <graphicsaccelerator.h>
#include <j2me/jdebug.h>

#include "lcd32bpp.h"
#include "lcdgdrvutil.h"
#include "lcdtransform.h"
#include "lcdbitblt.h"

LOCAL_C void FillTriangle32Bpp32
(
    const TAcceleratedBitmapInfo* aBitmap,
    const TPoint aPoints[],
    TUint32 aColor32Bpp,
    const TRect& aClipRect
)
{
    TRect clipRect(aBitmap->iSize);
    clipRect.Intersection(aClipRect);
    const TInt clipX1 = clipRect.iTl.iX;
    const TInt clipY1 = clipRect.iTl.iY;
    const TInt clipX2 = clipRect.iBr.iX;
    const TInt clipY2 = clipRect.iBr.iY;

    TInt i;

    TInt ymin=0;
    TInt ymax=0;
    TInt xmin=0;
    TInt xmax=0;

    for (i=1; i<3; i++)
    {
        if (aPoints[i].iX < aPoints[xmin].iX) xmin = i;
        if (aPoints[i].iX > aPoints[xmax].iX) xmax = i;
        if (aPoints[i].iY < aPoints[ymin].iY) ymin = i;
        if (aPoints[i].iY > aPoints[ymax].iY) ymax = i;
    }
    const TInt ymid = 3 - (ymax + ymin);


    TEdge edges[3];

    //
    // Long edge top to bottom.
    //
    edges[0].iDy = aPoints[ymax].iY - aPoints[ymin].iY;
    if (edges[0].iDy == 0)
    {
        return;
    }
    edges[0].iDx = aPoints[ymax].iX - aPoints[ymin].iX;
    edges[0].iX  = aPoints[ymin].iX;
    edges[0].iF  = 0;
    edges[0].iD  = edges[0].iDy;
    edges[0].iDe = Sign(edges[0].iDx);
    Increment(edges[0].iIx, edges[0].iIf, edges[0].iDx, edges[0].iDy);
    ASSERT(edges[0].iDy >= 0);

    //
    // Short top edge, or flat top
    //
    edges[1].iDx = aPoints[ymid].iX - aPoints[ymin].iX;
    edges[1].iDy = aPoints[ymid].iY - aPoints[ymin].iY;
    edges[1].iX  = aPoints[ymin].iX;
    edges[1].iF  = 0;
    edges[1].iD  = edges[1].iDy;
    edges[1].iDe = Sign(edges[1].iDx);
    ASSERT(edges[1].iDy >= 0);

    //
    // Short bottom edge or flat bottom
    //
    edges[2].iDx = aPoints[ymax].iX - aPoints[ymid].iX;
    edges[2].iDy = aPoints[ymax].iY - aPoints[ymid].iY;
    edges[2].iX  = aPoints[ymid].iX;
    edges[2].iF  = 0;
    edges[2].iD  = edges[2].iDy;
    edges[2].iDe = Sign(edges[2].iDx);
    ASSERT(edges[2].iDy >= 0);

    const TBool flatTop    = (edges[1].iDy == 0);
    const TBool flatBottom = (edges[2].iDy == 0);

    //
    // work out whether long edge is left most or right most.
    //
    // compare slopes of long edge and top edge.
    //
    TBool longEdgeRight;
    if (flatTop)
    {
        longEdgeRight = (aPoints[ymid].iX < aPoints[ymin].iX);
    }
    else
    {
        longEdgeRight = (edges[0].iDx*edges[1].iDy) > (edges[1].iDx*edges[0].iDy);
    }

    TInt y    = aPoints[ymin].iY;
    TInt yEnd = Min(aPoints[ymid].iY, clipY2);
    TEdge* el = NULL;
    TEdge* er = NULL;
    TInt m;     // number of lines to skip
    TInt x1;    // start of clipped scan (inclusive)
    TInt x2;    // end of clipped scan (exclusive), exclusive overrides inclusive

    TInt eliX;  // Locals used to speed access to edge information in loops.
    TInt eliF;
    TInt eliD;
    TInt eriX;
    TInt eriF;
    TInt eriD;

    TUint8* base = aBitmap->iAddress;
    TUint8* line = NULL;
    TInt linePitch = aBitmap->iLinePitch;
    TUint32* dst;
    TUint32* end;
    TUint32 color32 = (TUint32)aColor32Bpp;

    //
    // render top half.
    //
    if (!flatTop)
    {
        Increment(edges[1].iIx, edges[1].iIf, edges[1].iDx, edges[1].iDy);
        if (longEdgeRight)
        {
            er = &edges[0];
            el = &edges[1];
        }
        else
        {
            er = &edges[1];
            el = &edges[0];
        }
        eliX = el->iX;
        eliF = el->iF;
        eliD = el->iD;
        eriX = er->iX;
        eriF = er->iF;
        eriD = er->iD;

        //
        // Clip to top of clip rect.
        //
        if (y < clipY1)
        {
            TInt yTop = Min(clipY1, yEnd);

            m = (yTop - y);

            eliX += m*el->iIx;
            eliF += m*el->iIf;
            while (eliF > 0)
            {
                eliX ++;
                eliF -= eliD;
            }

            eriX += m*er->iIx;
            eriF += m*er->iIf;
            while (eriF > 0)
            {
                eriX ++;
                eriF -= eriD;
            }

            y = yTop;
        }

        ASSERT(((1 - eriD) <= eriF) && (eriF <= 0));
        ASSERT(((1 - eliD) <= eliF) && (eliF <= 0));

#ifdef PLOT_TOP_VERTEX
        // special case top vertex - can produce pimple so prob best avoided.
        if (aClipRect.Contains(aPoints[ymin]))
        {
            line = base + aPoints[ymin].iY*linePitch;
            ((TUint32*)line)[aPoints[ymin].iX] = color32;
        }
#endif

        line = base + y*linePitch;
        for (; y<yEnd; y++)
        {
            ASSERT(eliX <= eriX);
            if ((eliX < clipX2) && (eriX > clipX1))
            {
                x1 = Max(eliX, clipX1); // inclusive (ceil)
                x2 = Min(eriX, clipX2); // exclusive (floor)

                dst = (TUint32*)(line + x1*sizeof(TUint32));
                end = (TUint32*)(line + x2*sizeof(TUint32));
                while (dst < end)
                {
                    *dst++ = color32;
                }
            }

            eliX += el->iIx;
            eliF += el->iIf;
            if (eliF > 0)
            {
                eliX ++;
                eliF -= eliD;
            }

            eriX += er->iIx;
            eriF += er->iIf;
            if (eriF > 0)
            {
                eriX ++;
                eriF -= eriD;
            }

            line += linePitch;
        }

        el->iX = eliX;
        el->iF = eliF;
        el->iD = eliD;
        er->iX = eriX;
        er->iF = eriF;
        er->iD = eriD;
    }

    if (!flatBottom)
    {
        Increment(edges[2].iIx, edges[2].iIf, edges[2].iDx, edges[2].iDy);
        if (longEdgeRight)
        {
            // initialize short left edge
            er = &edges[0];
            el = &edges[2];
        }
        else
        {
            // initialize short right edge
            er = &edges[2];
            el = &edges[0];
        }
        eliX = el->iX;
        eliF = el->iF;
        eliD = el->iD;
        eriX = er->iX;
        eriF = er->iF;
        eriD = er->iD;

        //
        // clip to top edge of clip rect.
        //
        //
        // Clip to top of clip rect.
        //
        if (y < clipY1)
        {
            m = (clipY1 - y);

            eliX += m*el->iIx;
            eliF += m*el->iIf;
            while (eliF > 0)
            {
                eliX ++;
                eliF -= eliD;
            }

            eriX += m*er->iIx;
            eriF += m*er->iIf;
            while (eriF > 0)
            {
                eriX ++;
                eriF -= eriD;
            }
            y = clipY1;
        }

        line = base + y*linePitch;
        yEnd = Min(aPoints[ymax].iY, clipY2);
        for (; y<yEnd; y++)     // ignore last line - as pixel will be on bottom edge.
        {
            ASSERT(eliX <= eriX);
            if ((eliX < clipX2) && (eriX > clipX1))
            {
                x1 = Max(eliX, clipX1); // inclusive (ceil)
                x2 = Min(eriX, clipX2); // exclusive (floor)

                dst = (TUint32*)(line + x1*sizeof(TUint32));
                end = (TUint32*)(line + x2*sizeof(TUint32));
                while (dst < end)
                {
                    *dst++ = color32;
                }
            }

            eliX += el->iIx;
            eliF += el->iIf;
            if (eliF > 0)
            {
                eliX ++;
                eliF -= eliD;
            }

            eriX += er->iIx;
            eriF += er->iIf;
            if (eriF > 0)
            {
                eriX ++;
                eriF -= eriD;
            }

            line += linePitch;
        }

        el->iX = eliX;
        el->iF = eliF;
        el->iD = eliD;
        er->iX = eriX;
        er->iF = eriF;
        er->iD = eriD;
    }
}

LOCAL_C void FillTriangle32Bpp64
(
    const TAcceleratedBitmapInfo* aBitmap,
    const TPoint aPoints[],
    TUint32 aColor32Bpp,
    const TRect& aClipRect
)
{
    TRect clipRect(aBitmap->iSize);
    clipRect.Intersection(aClipRect);
    const TInt64 clipX1 = (TInt64)(clipRect.iTl.iX);
    const TInt64 clipY1 = (TInt64)(clipRect.iTl.iY);
    const TInt64 clipX2 = (TInt64)(clipRect.iBr.iX);
    const TInt64 clipY2 = (TInt64)(clipRect.iBr.iY);

    TInt i;

    TInt ymin=0;
    TInt ymax=0;
    TInt xmin=0;
    TInt xmax=0;

    for (i=1; i<3; i++)
    {
        if (aPoints[i].iX < aPoints[xmin].iX) xmin = i;
        if (aPoints[i].iX > aPoints[xmax].iX) xmax = i;
        if (aPoints[i].iY < aPoints[ymin].iY) ymin = i;
        if (aPoints[i].iY > aPoints[ymax].iY) ymax = i;
    }
    const TInt ymid = 3 - (ymax + ymin);

    // const TInt64 minX = aPoints[xmin].iX;
    // const TInt64 maxX = aPoints[xmax].iX;

    TEdge64 edges[3];

    //
    // Long edge top to bottom.
    //
    edges[0].iDy = (TInt64)(aPoints[ymax].iY) - (TInt64)(aPoints[ymin].iY);
    if (edges[0].iDy == 0)
    {
        return;
    }
    edges[0].iDx = (TInt64)(aPoints[ymax].iX) - (TInt64)(aPoints[ymin].iX);
    edges[0].iX  = (TInt64)(aPoints[ymin].iX);
    edges[0].iF  = 0;
    edges[0].iD  = edges[0].iDy;
    edges[0].iDe = Sign(edges[0].iDx);
    Increment(edges[0].iIx, edges[0].iIf, edges[0].iDx, edges[0].iDy);
    ASSERT(edges[0].iDy >= 0);

    //
    // Short top edge, or flat top
    //
    edges[1].iDx = (TInt64)(aPoints[ymid].iX) - (TInt64)(aPoints[ymin].iX);
    edges[1].iDy = (TInt64)(aPoints[ymid].iY) - (TInt64)(aPoints[ymin].iY);
    edges[1].iX  = (TInt64)(aPoints[ymin].iX);
    edges[1].iF  = 0;
    edges[1].iD  = edges[1].iDy;
    edges[1].iDe = Sign(edges[1].iDx);
    ASSERT(edges[1].iDy >= 0);

    //
    // Short bottom edge or flat bottom
    //
    edges[2].iDx = (TInt64)(aPoints[ymax].iX) - (TInt64)(aPoints[ymid].iX);
    edges[2].iDy = (TInt64)(aPoints[ymax].iY) - (TInt64)(aPoints[ymid].iY);
    edges[2].iX  = (TInt64)(aPoints[ymid].iX);
    edges[2].iF  = 0;
    edges[2].iD  = edges[2].iDy;
    edges[2].iDe = Sign(edges[2].iDx);
    ASSERT(edges[2].iDy >= 0);

    const TBool flatTop    = (edges[1].iDy == 0);
    const TBool flatBottom = (edges[2].iDy == 0);

    //
    // work out whether long edge is left most or right most.
    //
    // compare slopes of long edge and top edge.
    //
    TBool longEdgeRight;
    if (flatTop)
    {
        longEdgeRight = (aPoints[ymid].iX < aPoints[ymin].iX);
    }
    else
    {
        longEdgeRight = (edges[0].iDx*edges[1].iDy) > (edges[1].iDx*edges[0].iDy);
    }

    TInt64   y    = (TInt64)aPoints[ymin].iY;
    TInt64   yEnd = Min(aPoints[ymid].iY, clipY2);
    TEdge64* el   = NULL;
    TEdge64* er   = NULL;
    TInt64   m;     // number of lines to skip
    TInt64   x1;    // start of clipped scan (inclusive)
    TInt64   x2;    // end of clipped scan (exclusive), exclusive overrides inclusive

    TInt64 eliX;    // Locals used to speed access to edge information in loops.
    TInt64 eliF;
    TInt64 eliD;
    TInt64 eriX;
    TInt64 eriF;
    TInt64 eriD;

    TUint8* base = aBitmap->iAddress;
    TUint8* line = NULL;
    TInt linePitch = aBitmap->iLinePitch;
    TUint32* dst;
    TUint32* end;
    TUint32 color32 = (TUint32)aColor32Bpp;

    //
    // render top half.
    //
    if (!flatTop)
    {
        Increment(edges[1].iIx, edges[1].iIf, edges[1].iDx, edges[1].iDy);
        if (longEdgeRight)
        {
            er = &edges[0];
            el = &edges[1];
        }
        else
        {
            er = &edges[1];
            el = &edges[0];
        }
        eliX = el->iX;
        eliF = el->iF;
        eliD = el->iD;
        eriX = er->iX;
        eriF = er->iF;
        eriD = er->iD;

        //
        // Clip to top of clip rect.
        //
        if (y < clipY1)
        {
            TInt64 yTop = Min(clipY1, yEnd);

            m = (yTop - y);

            double leftSlope = (double)(el->iDx)/(double)(el->iDy);

            eliX += (leftSlope * ((double)m));

            double rightSlope = (double)(er->iDx)/(double)(er->iDy);

            eriX += (rightSlope * ((double)m));
            y = yTop;
        }

        ASSERT(((1 - eriD) <= eriF) && (eriF <= 0));
        ASSERT(((1 - eliD) <= eliF) && (eliF <= 0));

#ifdef PLOT_TOP_VERTEX
        // special case top vertex - can produce pimple so prob best avoided.
        if (aClipRect.Contains(aPoints[ymin]))
        {
            line = base + aPoints[ymin].iY*linePitch;
            ((TUint32*)line)[aPoints[ymin].iX] = color32;
        }
#endif

        line = base + y*linePitch;
        for (; y<yEnd; y++)
        {
            ASSERT(eliX <= eriX);
            if ((eliX < clipX2) && (eriX > clipX1))
            {
                x1 = Max(eliX, clipX1); // inclusive (ceil)
                x2 = Min(eriX, clipX2); // exclusive (floor)

                dst = (TUint32*)(line + x1*sizeof(TUint32));
                end = (TUint32*)(line + x2*sizeof(TUint32));
                while (dst < end)
                {
                    *dst++ = color32;
                }
            }
            eliX += el->iIx;
            eliF += el->iIf;
            if (eliF > 0)
            {
                eliX ++;
                eliF -= eliD;
            }

            eriX += er->iIx;
            eriF += er->iIf;
            if (eriF > 0)
            {
                eriX ++;
                eriF -= eriD;
            }

            line += linePitch;
        }

        el->iX = eliX;
        el->iF = eliF;
        el->iD = eliD;
        er->iX = eriX;
        er->iF = eriF;
        er->iD = eriD;
    }

    if (!flatBottom)
    {
        Increment(edges[2].iIx, edges[2].iIf, edges[2].iDx, edges[2].iDy);
        if (longEdgeRight)
        {
            // initialize short left edge
            er = &edges[0];
            el = &edges[2];
        }
        else
        {
            // initialize short right edge
            er = &edges[2];
            el = &edges[0];
        }
        eliX = el->iX;
        eliF = el->iF;
        eliD = el->iD;
        eriX = er->iX;
        eriF = er->iF;
        eriD = er->iD;

        //
        // clip to top edge of clip rect.
        //
        //
        // Clip to top of clip rect.
        //
        if (y < clipY1)
        {
            m = (clipY1 - y);

            double leftSlope = (double)(el->iDx)/(double)(el->iDy);

            eliX += (leftSlope * m);

            double rightSlope = (double)(er->iDx)/(double)(er->iDy);

            eriX += (rightSlope * m);

            y = clipY1;
        }

        line = base + y*linePitch;
        yEnd = Min(aPoints[ymax].iY, clipY2);
        for (; y<yEnd; y++)     // ignore last line - as pixel will be on bottom edge.
        {
            ASSERT(eliX <= eriX);
            if ((eliX < clipX2) && (eriX > clipX1))
            {
                x1 = Max(eliX, clipX1); // inclusive (ceil)
                x2 = Min(eriX, clipX2); // exclusive (floor)

                dst = (TUint32*)(line + x1*sizeof(TUint32));
                end = (TUint32*)(line + x2*sizeof(TUint32));
                while (dst < end)
                {
                    *dst++ = color32;
                }
            }

            eliX += el->iIx;
            eliF += el->iIf;
            if (eliF > 0)
            {
                eliX ++;
                eliF -= eliD;
            }

            eriX += er->iIx;
            eriF += er->iIf;
            if (eriF > 0)
            {
                eriX ++;
                eriF -= eriD;
            }

            line += linePitch;
        }

        el->iX = eliX;
        el->iF = eliF;
        el->iD = eliD;
        er->iX = eriX;
        er->iF = eriF;
        er->iD = eriD;
    }
}

LOCAL_C TBool IsPathologicalTriangle(const TPoint aPoints[3])
{
    TInt minX = aPoints[0].iX;
    TInt maxX = aPoints[0].iX;
    TInt minY = aPoints[0].iY;
    TInt maxY = aPoints[0].iY;

    for (TInt i = 1; i <= 2; i++)
    {
        TInt x = aPoints[i].iX;
        TInt y = aPoints[i].iY;

        if (x < minX)
        {
            minX = x;
        }
        if (x > maxX)
        {
            maxX = x;
        }
        if (y < minY)
        {
            minY = y;
        }
        if (y > maxY)
        {
            maxY = y;
        }
    }
    if (minX < 0)
    {
        if (maxX >= (0x7FFFFFFF + minX))
        {
            return ETrue;
        }
        if (-minX > 0xFFFFF)
        {
            return ETrue;
        }
    }
    if (maxX > 0)
    {
        if ((maxX == 0x7FFFFFFF) && (minX == 0))
        {
            return ETrue;
        }
        if (maxX > 0xFFFFF)
        {
            return ETrue;
        }
    }
    if (minY < 0)
    {
        if (maxY >= (0x7FFFFFFF + minY))
        {
            return ETrue;
        }
        if (-minY > 0xFFFFF)
        {
            return ETrue;
        }
    }
    if (minY > 0)
    {
        if ((maxY == 0x7FFFFFFF) && (minX == 0))
        {
            return ETrue;
        }
        if (minY > 0xFFFFF)
        {
            return ETrue;
        }
    }
    return EFalse;
}

extern void FillTriangle32Bpp
(
    const TAcceleratedBitmapInfo* aBitmap,
    const TPoint aPoints[],
    TUint32 aColor32Bpp,
    const TRect& aClipRect
)
{
    if (!IsPathologicalTriangle(aPoints))
    {
        FillTriangle32Bpp32(aBitmap, aPoints, aColor32Bpp, aClipRect);
    }
    else
    {
        FillTriangle32Bpp64(aBitmap, aPoints, aColor32Bpp, aClipRect);
    }
}

LOCAL_C void BlitLineThirtyTwoBppSimple
(
    TUint8* aDstAddress,
    TInt    aWidth,
    TUint8* aColorAddress,
    TInt    DEBUG_ONLY(aColorPixelPitch)
)
{
    ASSERT(aColorPixelPitch == sizeof(TUint32));
    Mem::Move(aDstAddress, aColorAddress, aWidth * sizeof(TUint32));
}


extern void BitBltThirtyTwoBppSimple
(
    const TAcceleratedBitmapInfo*   aDstColorBitmap,
    const TAcceleratedBitmapInfo*   /*aDstAlphaBitmap*/,
    const TRect&                    aDstRect,
    const TAcceleratedBitmapInfo*   aSrcColorBitmap,
    const TAcceleratedBitmapInfo*   /*aSrcAlphaBitmap*/,
    const TLcdTransform&            aTransform
)
{
    //
    // Translation or translation & vertical reflection case.
    //
    ASSERT(aTransform.iDuDx == 1);
    ASSERT(aTransform.iDuDy == 0);
    ASSERT(aTransform.iDvDx == 0);
    ASSERT(aTransform.iDvDy == 1 || aTransform.iDvDy == -1);

    GenericBlit(aDstColorBitmap, aDstRect, aSrcColorBitmap, aTransform,
                BlitLineThirtyTwoBppSimple);
}


LOCAL_C void BlitLineThirtyTwoBpp
(
    TUint8* aDstAddress,
    TInt    aWidth,
    TUint8* aColorAddress,
    TInt    aColorPixelPitch
)
{
    TUint32* dst = (TUint32*)aDstAddress;
    TUint32* end = dst + aWidth;

    TUint8* colorAddr = aColorAddress;
    while (dst < end)
    {
        *dst++ = *(TUint32*)colorAddr;
        colorAddr += aColorPixelPitch;
    }
}


extern void BitBltThirtyTwoBpp
(
    const TAcceleratedBitmapInfo*   aDstColorBitmap,
    const TAcceleratedBitmapInfo*   /*aDstAlphaBitmap*/,
    const TRect&                    aDstRect,
    const TAcceleratedBitmapInfo*   aSrcColorBitmap,
    const TAcceleratedBitmapInfo*   /*aSrcAlphaBitmap*/,
    const TLcdTransform&            aTransform
)
{
    GenericBlit(aDstColorBitmap, aDstRect, aSrcColorBitmap, aTransform,
                BlitLineThirtyTwoBpp);
}

extern void BitBltThirtyTwoBppEightBpp
(
    const TAcceleratedBitmapInfo*   aDstColorBitmap,
    const TAcceleratedBitmapInfo*   aDstAlphaBitmap,
    const TRect&                    aDstRect,
    const TAcceleratedBitmapInfo*   aSrcColorBitmap,
    const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
    const TLcdTransform&            aTransform
)
{
    BitBltThirtyTwoBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform);
    BitBltEightBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform);
}

extern void BitBltThirtyTwoBppOneBpp
(
    const TAcceleratedBitmapInfo*   aDstColorBitmap,
    const TAcceleratedBitmapInfo*   aDstAlphaBitmap,
    const TRect&                    aDstRect,
    const TAcceleratedBitmapInfo*   aSrcColorBitmap,
    const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
    const TLcdTransform&            aTransform
)
{
    BitBltThirtyTwoBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform);
    BitBltOneBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform);
}

extern void BitBltThirtyTwoBppThirtyTwoBpp
(
    const TAcceleratedBitmapInfo*   aDstColorBitmap,
    const TAcceleratedBitmapInfo*   aDstAlphaBitmap,
    const TRect&                    aDstRect,
    const TAcceleratedBitmapInfo*   aSrcColorBitmap,
    const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
    const TLcdTransform&            aTransform
)
{
    BitBltThirtyTwoBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform);
    BitBltThirtyTwoBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform);
}