javauis/lcdui_akn/lcdgd/src/lcdgdev.cpp
branchRCL_3
changeset 19 04becd199f91
child 59 e5618cc85d74
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdgd/src/lcdgdev.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,641 @@
+/*
+* 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 <lcdgdrv.h>
+#include "lcdgdrvif.h"
+#include "calctransform.h"
+#include "lcdgdev.h"
+
+CLcdGraphicsDeviceImpl::CLcdGraphicsDeviceImpl
+(
+    CLcdGraphicsDriver& aDriver,
+    const TImageType& aTargetType,
+    CRenderFunctions* aRenderers,
+    const TColorMap& aColorMap,
+    const TDrawFunctions& aDrawFunctions
+)
+        : iDriver(aDriver)
+        , iRenderers(aRenderers)
+        , iColorMap(aColorMap)
+        , iDrawFunctions(aDrawFunctions)
+{
+    iRenderKey.iTargetType = aTargetType;
+    ASSERT(iDrawFunctions.iDisplayMode == aTargetType.iColorMode);
+}
+
+CLcdGraphicsDeviceImpl::~CLcdGraphicsDeviceImpl()
+{
+    delete iRenderers;
+}
+
+
+TUint32 CLcdGraphicsDeviceImpl::DrawingCaps() const
+{
+    const TInt renderCaps = (CLcdGraphicsDevice::ECapDrawRegion | CLcdGraphicsDevice::ECapCopyRegion);
+    return iDrawFunctions.iDrawCaps | renderCaps;
+}
+
+TUint32 CLcdGraphicsDeviceImpl::Quantize(TUint32 aRGB) const
+{
+    return (*iColorMap.iQuantize)(aRGB);
+}
+
+/**
+ * Transforming biblt from aColorBitmap/aAlphaBitmap to target surface
+ * Composites source image over destination image (either alpha blending
+ * or masking as appropriate to <CODE>aSrcTransparency</CODE>).
+ */
+TInt CLcdGraphicsDeviceImpl::DrawRegion
+(
+    const TAcceleratedBitmapInfo*   aDstBitmap,
+    const TRect&                    aDstRect,
+    const TAcceleratedBitmapInfo*   aSrcColorBitmap,
+    const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
+    TTransparency                   aSrcTransparency,
+    const TRect&                    aSrcRect,
+    TTransformType                  aSrcTransform,
+    const TRect&                    aClipRect
+)
+{
+    TInt err = KErrNotSupported;
+
+    TImageType sourceType;
+    sourceType.iColorMode = aSrcColorBitmap->iDisplayMode;
+    sourceType.iAlphaMode = aSrcAlphaBitmap ? aSrcAlphaBitmap->iDisplayMode : ENone;
+    sourceType.iTransparency = aSrcTransparency;
+
+    iRenderKey.iSourceType = TCompactImageType(sourceType);
+    iRenderKey.iTransform = (1<<aSrcTransform);
+    iRenderKey.iComposite  = ECompositeSrcOver;
+
+    const TImageRenderer* renderer = iRenderers->Get(iRenderKey);
+    if (renderer)
+    {
+        TImageRenderFunction drawRegion = renderer->iFunction;
+
+        // calc source to target transform
+        TLcdTransform transform = CalcTransform(aDstRect, aSrcRect, aSrcTransform);
+
+        TRect dstRect(aDstRect);
+        TRect srcRect(aSrcRect);
+        TRect srcClipRect(aSrcColorBitmap->iSize);
+        TRect dstClipRect(aDstBitmap->iSize);
+
+        // clip cliprect to device rect
+        dstClipRect.Intersection(aClipRect);
+
+        // calculate source and target rects clipped to src and target bounds.
+        ClipTransformRect(dstRect, srcRect, dstClipRect, srcClipRect, transform);
+
+        dstRect.Intersection(dstClipRect);
+
+        if (!dstRect.IsEmpty())
+        {
+            // calc target to source transform.
+            transform = transform.Inverse();
+
+            ASSERT(CheckBounds(aDstBitmap->iSize, aSrcColorBitmap->iSize, dstRect, transform));
+
+            (*drawRegion)(aDstBitmap, NULL, dstRect, aSrcColorBitmap, aSrcAlphaBitmap, transform);
+        }
+
+        err = KErrNone;
+    }
+
+    return err;
+}
+
+/**
+ * Transforming biblt from <CODE>aSrcColorBitmap,aSrcAlphaBitmap<CODE>
+ * to <CODE>aDstColorBitmap,aDstAlphaBitmap</CODE>.
+ * Copies source image pixels to destination image converting color
+ * and transparency pixels to the destination format. Supports translation
+ * and symmetry transformation of source image region, specified by
+ * <CODE>aSrcTransform</CODE>.
+ */
+TInt CLcdGraphicsDeviceImpl::CopyRegion
+(
+    const TAcceleratedBitmapInfo* aDstBitmap,
+    const TRect&                    aDstRect,
+    const TAcceleratedBitmapInfo*   aSrcColorBitmap,
+    const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
+    TTransparency                   aSrcTransparency,
+    const TRect&                    aSrcRect,
+    TTransformType                  aSrcTransform,
+    const TRect&                    aClipRect
+)
+{
+    TInt err = KErrNotSupported;
+    ASSERT(aDstBitmap->iAddress);
+
+    TImageType sourceType;
+
+    sourceType.iColorMode = aSrcColorBitmap->iDisplayMode;
+    sourceType.iAlphaMode = aSrcAlphaBitmap ? aSrcAlphaBitmap->iDisplayMode : ENone;
+    sourceType.iTransparency = aSrcTransparency;
+
+    iRenderKey.iSourceType = TCompactImageType(sourceType);
+    iRenderKey.iTransform = (1<<aSrcTransform);
+    iRenderKey.iComposite  = ECompositeSrcCopy;
+
+    const TImageRenderer* renderer = iRenderers->Get(iRenderKey);
+    if (renderer)
+    {
+        TImageRenderFunction copyRegion = renderer->iFunction;
+
+        // calc source to target transform
+        TLcdTransform transform = CalcTransform(aDstRect, aSrcRect, aSrcTransform);
+
+        TRect dstRect(aDstRect);
+        TRect srcRect(aSrcRect);
+        TRect srcClipRect(aSrcColorBitmap->iSize);
+        TRect dstClipRect(aDstBitmap->iSize);
+
+        // clip cliprect to device rect
+        dstClipRect.Intersection(aClipRect);
+
+        // clip source and target rects
+        ClipTransformRect(dstRect, srcRect, dstClipRect, srcClipRect, transform);
+
+        // check src and dst rects still correspond
+        ASSERT(CheckTransform(dstRect, srcRect, transform));
+
+        dstRect.Intersection(dstClipRect);
+
+        if (!dstRect.IsEmpty())
+        {
+            // calc target to source transform.
+            transform = transform.Inverse();
+
+            // check source and dst rects lie within bounds
+            ASSERT(CheckBounds(aDstBitmap->iSize, aSrcColorBitmap->iSize, dstRect, transform));
+
+            (*copyRegion)(aDstBitmap, NULL, dstRect, aSrcColorBitmap, aSrcAlphaBitmap, transform);
+        }
+
+        err = KErrNone;
+    }
+
+    return err;
+}
+
+
+/*
+ * Draw line from aStart to aEnd including both end points and
+ * using line style TStrokeStyle.
+ */
+TInt CLcdGraphicsDeviceImpl::DrawLine
+(
+    const TAcceleratedBitmapInfo* aDstBitmap,
+    const TPoint& aStart,
+    const TPoint& aEnd,
+    TUint32 aRGB,
+    TStrokeStyle aStyle,
+    const TRect& aClipRect
+)
+{
+    TInt caps = ECapDrawLine;
+    if (aStyle == EStrokeDotted)
+    {
+        caps |= ECapStrokeDotted;
+    }
+    if ((iDrawFunctions.iDrawCaps & caps) != caps)
+    {
+        return KErrNotSupported;
+    }
+    ASSERT(iDrawFunctions.iDrawLine);
+    (*iDrawFunctions.iDrawLine)(aDstBitmap, aStart, aEnd, (*iColorMap.iForward)(aRGB), aStyle, aClipRect);
+    return KErrNone;
+}
+
+/**
+ * Draw outline of <CODE>aRect</CODE>
+ */
+TInt CLcdGraphicsDeviceImpl::DrawRect
+(
+    const TAcceleratedBitmapInfo* aDstBitmap,
+    const TRect& aRect,
+    TUint32      aRGB,
+    TStrokeStyle aStyle,
+    const TRect& aClipRect
+)
+{
+    TInt caps = ECapDrawRect;
+    if (aStyle == EStrokeDotted)
+    {
+        caps |= ECapStrokeDotted;
+    }
+    if ((iDrawFunctions.iDrawCaps & caps) != caps)
+    {
+        return KErrNotSupported;
+    }
+    ASSERT(iDrawFunctions.iDrawRect);
+    (*iDrawFunctions.iDrawRect)(aDstBitmap, aRect, (*iColorMap.iForward)(aRGB), aStyle, aClipRect);
+    return KErrNone;
+}
+
+/**
+ * Fill interior of <CODE>aRect</CODE> with color <CODE>aRGB</CODE>
+ */
+TInt CLcdGraphicsDeviceImpl::FillRect
+(
+    const TAcceleratedBitmapInfo* aDstBitmap,
+    const TRect& aRect,
+    TUint32      aRGB,
+    const TRect& aClipRect
+)
+{
+    if (!(iDrawFunctions.iDrawCaps & ECapFillRect))
+    {
+        return KErrNotSupported;
+    }
+    ASSERT(iDrawFunctions.iFillRect);
+    (*iDrawFunctions.iFillRect)(aDstBitmap, aRect, (*iColorMap.iForward)(aRGB), aClipRect);
+    return KErrNone;
+}
+
+/**
+ * Draw the arc of an ellipse bounded by aBoundingRect in device coordinates,
+ * starting the arc at aStartAngle from the ellipse horizontal axis and
+ * extending for aArcAngle degrees anticlockwise. Draw with color aRGB and
+ * clip to aClipRect in device coords.
+ */
+TInt CLcdGraphicsDeviceImpl::DrawArc
+(
+    const TAcceleratedBitmapInfo* aDstBitmap,
+    const TRect& aBoundingRect,
+    const TInt aStartAngle,
+    const TInt aArcAngle,
+    TUint32 aRGB,
+    TStrokeStyle aStyle,
+    const TRect& aClipRect
+)
+{
+    TInt caps = ECapDrawRect;
+    if (aStyle == EStrokeDotted)
+    {
+        caps |= ECapStrokeDotted;
+    }
+    if ((iDrawFunctions.iDrawCaps & caps) != caps)
+    {
+        return KErrNotSupported;
+    }
+    ASSERT(iDrawFunctions.iDrawArc);
+    (*iDrawFunctions.iDrawArc)(aDstBitmap, aBoundingRect, aStartAngle, aArcAngle, (*iColorMap.iForward)(aRGB), aStyle, aClipRect);
+    return KErrNone;
+}
+
+/**
+ * Fill the region bounded by an arc and the radii of its end points of an ellipse bounded
+ * by aBoundingRect in device coordinates. The first radius lies at aStartAngle from the
+ * ellipse horizontal axis and the second radies lies aArcAngle degrees anticlockwise
+ * from the first. Fill with color aRGB and clip to aClipRect in device coords.
+ */
+TInt CLcdGraphicsDeviceImpl::FillArc
+(
+    const TAcceleratedBitmapInfo* aDstBitmap,
+    const TRect& aBoundingRect,
+    const TInt aStartAngle,
+    const TInt aArcAngle,
+    TUint32 aRGB,
+    const TRect& aClipRect
+)
+{
+    if (!(iDrawFunctions.iDrawCaps & ECapFillArc))
+    {
+        return KErrNotSupported;
+    }
+    ASSERT(iDrawFunctions.iFillArc);
+    (*iDrawFunctions.iFillArc)(aDstBitmap, aBoundingRect, aStartAngle, aArcAngle, (*iColorMap.iForward)(aRGB), aClipRect);
+    return KErrNone;
+}
+
+/**
+ * Fill a triangle in device coordinates with color aRGB,
+ * clipping to aClipRect in device coordinates.
+ */
+TInt CLcdGraphicsDeviceImpl::FillTriangle
+(
+    const TAcceleratedBitmapInfo* aDstBitmap,
+    const TPoint aPoints[3],
+    TUint32 aRGB,
+    const TRect& aClipRect
+)
+{
+    if (!(iDrawFunctions.iDrawCaps & ECapFillTriangle))
+    {
+        return KErrNotSupported;
+    }
+    ASSERT(iDrawFunctions.iFillTriangle);
+    (*iDrawFunctions.iFillTriangle)(aDstBitmap, aPoints, (*iColorMap.iForward)(aRGB), aClipRect);
+    return KErrNone;
+}
+
+TInt CLcdGraphicsDeviceImpl::DrawText
+(
+    const TAcceleratedBitmapInfo* /*aDstBitmap*/,
+    const TDesC& /*aText*/,
+    const TPoint& /*aPoint*/,
+    const CFont* /*aFont*/,
+    TUint32 /*aColor*/,
+    const TRect& /*aClipRect*/
+)
+{
+    return KErrNotSupported;
+}
+
+/**
+ * This function is used, when image is drawn and rendering
+ * target is framebuffer of CanavsGraphicsItem.
+ */
+TInt CLcdGraphicsDeviceImpl::DrawRegionForCanvasGraphicsItem
+(
+    const TAcceleratedBitmapInfo*               aDstBitmap,
+    const TRect&                                aDstRect,
+    const TAcceleratedBitmapInfo*               aSrcColorBitmap,
+    const TAcceleratedBitmapInfo*             /*aSrcAlphaBitmap*/,
+    TTransparency                             /*aSrcTransparency*/,
+    const TRect&                                aSrcRect,
+    TTransformType                              aSrcTransform,
+    const TRect&                                aClipRect,
+    const TCanvasGraphicsItemOperationsType&    aOperation
+)
+{
+    TInt err = KErrNotSupported;
+
+    // calc source to target transform
+    TLcdTransform transform = CalcTransform(aDstRect, aSrcRect, aSrcTransform);
+
+    TRect dstRect(aDstRect);
+    TRect srcRect(aSrcRect);
+    TRect srcClipRect(aSrcColorBitmap->iSize);
+    TRect dstClipRect(aDstBitmap->iSize);
+
+    // clip cliprect to device rect
+    dstClipRect.Intersection(aClipRect);
+
+    // calculate source and target rects clipped to src and target bounds.
+    ClipTransformRect(dstRect, srcRect, dstClipRect, srcClipRect, transform);
+
+    dstRect.Intersection(dstClipRect);
+
+    if (!dstRect.IsEmpty())
+    {
+        // calc target to source transform.
+        transform = transform.Inverse();
+
+        ASSERT(CheckBounds(aDstBitmap->iSize, aSrcColorBitmap->iSize, dstRect, transform));
+
+        ASSERT(aDstBitmap->iDisplayMode == EColor16MA);
+        ASSERT(aSrcColorBitmap->iDisplayMode == EColor16MA);
+
+        DoBlit(aDstBitmap, dstRect, aSrcColorBitmap, transform, aOperation);
+    }
+
+    err = KErrNone;
+
+    return err;
+}
+
+// support for rendering image on CanavsGraphicsItem frame buffer
+TInt CLcdGraphicsDeviceImpl::PixelPitch(const TAcceleratedBitmapInfo* aBitmap)
+{
+    switch (aBitmap->iDisplayMode)
+    {
+    case EColor64K:
+    case EColor4K:
+        return 2;
+    case EColorARGB8888:
+    case EColor16MU:
+        return 4;
+    case EGray256:
+        return 1;
+    }
+
+    // Any other display mode is either invalid, or has a fractional number of
+    // bytes per pixel, and cannot be handled by this routine.
+    ASSERT(EFalse);
+    return 0;   // Pacify the compiler
+}
+
+// support for rendering image on CanavsGraphicsItem frame buffer
+void CLcdGraphicsDeviceImpl::DoBlit
+(
+    const TAcceleratedBitmapInfo*               aDstColorBitmap,
+    const TRect&                                aDstRect,       // must be clipped to destination
+    const TAcceleratedBitmapInfo*               aSrcColorBitmap,
+    const TLcdTransform&                        aTransform,     // includes anchor
+    const TCanvasGraphicsItemOperationsType&    aOperation
+)
+{
+    ASSERT(aDstColorBitmap != NULL);
+    ASSERT(aSrcColorBitmap != NULL);
+
+    TPoint srcPoint = aTransform(aDstRect.iTl);
+
+    TInt dudx = aTransform.iDuDx;
+    TInt dudy = aTransform.iDuDy;
+    TInt dvdx = aTransform.iDvDx;
+    TInt dvdy = aTransform.iDvDy;
+
+    //
+    // For each bitmap, calculate the starting address and byte offsets to the
+    // next address for one line down and one pixel right.
+    //
+    const TInt dstLinePitch = aDstColorBitmap->iLinePitch;
+    const TInt dstPixelPitch = PixelPitch(aDstColorBitmap);
+    TUint8* dstAddress = aDstColorBitmap->iAddress;
+    dstAddress += aDstRect.iTl.iY * dstLinePitch + aDstRect.iTl.iX * dstPixelPitch;
+
+    const TInt colorLinePitch = aSrcColorBitmap->iLinePitch;
+    const TInt colorPixelPitch = PixelPitch(aSrcColorBitmap);
+    TUint8* colorAddress = aSrcColorBitmap->iAddress;
+    colorAddress += srcPoint.iY * colorLinePitch + srcPoint.iX * colorPixelPitch;
+
+    // For the source bitmap, also calculate the pitch to the next address for
+    // one line down and one pixel right in the destination bitmap.
+    const TInt colorDstLinePitch = colorLinePitch * dvdy + colorPixelPitch * dudy;
+    const TInt colorDstPixelPitch = colorLinePitch * dvdx + colorPixelPitch * dudx;
+
+    //
+    // Iterate over destination pixels.
+    //
+    const TInt width = aDstRect.Width();
+    TInt h = aDstRect.Height();
+    while (h-- > 0)
+    {
+        switch (aOperation)
+        {
+        case ECanvasGraphicsItemImageRendering:
+            DoBlitLineForImage(dstAddress, width, colorAddress, colorDstPixelPitch);
+            break;
+        case ECanvasGraphicsItemRGBRendering:
+            DoBlitLineForRgb(dstAddress, width, colorAddress, colorDstPixelPitch);
+            break;
+        }
+
+        dstAddress += dstLinePitch;
+        colorAddress += colorDstLinePitch;
+    }
+}
+
+// support for rendering image on CanavsGraphicsItem frame buffer
+void CLcdGraphicsDeviceImpl::DoBlitLineForImage
+(
+    TUint8* aDstAddress,
+    TInt    aWidth,
+    TUint8* aColorAddress,
+    TInt    aColorPixelPitch
+)
+{
+    TUint32* dst = (TUint32*)(aDstAddress);
+    TUint32* end = dst + aWidth;
+
+    TUint8* colorAddr = aColorAddress;
+
+    while (dst < end)
+    {
+        TUint32 dstColor = *dst;
+        TUint32 srcColor = *(TUint32*)colorAddr;
+
+        TUint32 mask = (TUint32)(((TInt32)srcColor) >> 24); // Sign extend down.
+        ASSERT(mask == 0 || mask == (TUint32)-1);
+
+#ifdef RD_JAVA_NGA_ENABLED
+        if (mask)
+        {
+            // Note that the target is not always opaque anymore
+            dstColor = srcColor;
+        }
+#else // !RD_JAVA_NGA_ENABLED
+        dstColor = (dstColor & ~mask) | (srcColor & mask);
+#endif // RD_JAVA_NGA_ENABLED
+
+        *dst++ = dstColor;
+        colorAddr += aColorPixelPitch;
+    }
+}
+
+// support for rendering image on CanavsGraphicsItem frame buffer
+void CLcdGraphicsDeviceImpl::DoBlitLineForRgb
+(
+    TUint8* aDstAddress,
+    TInt    aWidth,
+    TUint8* aColorAddress,
+    TInt    aColorPixelPitch
+)
+{
+    TUint32* dstAddress = (TUint32*)(aDstAddress);
+    TUint32* end = dstAddress + aWidth;
+
+    TUint8* srcAddress = aColorAddress;
+
+    while (dstAddress < end)
+    {
+        const TUint32 src=*(TUint32*)srcAddress;
+
+        if (src >= 0xFF000000)
+        {
+            *(TUint32*)dstAddress = src;
+        }
+        else
+        {
+            const TUint32 srcAlpha = src >> 24;
+
+            if (srcAlpha)
+            {
+                TUint32 destA;
+                TUint32 destAG;
+                TUint32 destRB;
+                TUint32 destMultAlpha;
+
+                const TUint32 dst = *(TUint32*)dstAddress;
+                const TUint32 dstAlpha = dst >> 24;
+
+                destA = dstAlpha << 16;
+                destA = destA * (0x100 - srcAlpha);
+                destA += srcAlpha << 24;
+                destMultAlpha = (((0x100 - srcAlpha) * dstAlpha) >> 8) + 1;
+
+                const TUint32 srcPixel = *(TUint32*)srcAddress;
+                const TUint32 dstPixel = *(TUint32*)dstAddress;
+
+                destAG = (dstPixel & 0xFF00FF00) >> 8;
+                destAG = destAG * destMultAlpha;
+                TUint32 srcAG = (srcPixel & 0xFF00FF00) >> 8;
+                destAG &= 0xFF00FF00;
+                TUint32 alphaPlus1 = srcAlpha + 1;
+                destAG += srcAG * alphaPlus1;
+
+                destRB = dstPixel & 0x00FF00FF;
+                destRB = destRB * destMultAlpha;
+                destRB &= 0xFF00FF00;
+                TUint32 srcRB = (srcPixel & 0x00FF00FF);
+                destRB += srcRB * alphaPlus1;
+                destRB >>= 8;
+
+                *(TUint32*)dstAddress = (destAG & 0x0000FF00) |
+                                        (destRB & 0x00FF00FF) |
+                                        (destA & 0xFF000000);
+            }
+        }
+
+        dstAddress++;
+        srcAddress += aColorPixelPitch;
+    } // while( dstAddress < end )
+}
+
+CRenderFunctions::~CRenderFunctions()
+{
+    iEntries.Reset();
+    iEntries.Close();
+}
+
+const TImageRenderer* CRenderFunctions::Get(const TRenderKey& aKey)
+{
+    if (iLast && (iLast->iKey == aKey))
+    {
+        return &(iLast->iRenderer);
+    }
+    const TInt count = iEntries.Count();
+    for (TInt index=0; index<count; ++index)
+    {
+        const TRenderEntry& entry = iEntries[index];
+        if (entry.iKey.Match(aKey))
+        {
+            if (entry.iKey.iTransform == (1<<ETransNone))
+            {
+                // only cache no-trans variants.
+                iLast = &entry;
+            }
+            return &entry.iRenderer;
+        }
+    }
+    return NULL;
+}
+
+void CRenderFunctions::AppendL(const TImageRenderer& aRenderer)
+{
+    TRenderEntry entry;
+    entry.iKey.iTargetType = aRenderer.iTargetType;
+    entry.iKey.iSourceType = aRenderer.iSourceType;
+    entry.iKey.iTransform  = aRenderer.iTransformMask;
+    entry.iKey.iComposite   = aRenderer.iCompositeRule;
+    entry.iRenderer = aRenderer;
+    iEntries.AppendL(entry);
+}