javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtjavabufferdrawer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 21 Jun 2010 15:32:50 +0300
branchRCL_3
changeset 46 4376525cdefb
parent 24 0fd27995241b
permissions -rw-r--r--
Revision: v2.1.30 Kit: 2010125

/*******************************************************************************
 * Copyright (c) 2008 - 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Nokia Corporation - S60 implementation
 *******************************************************************************/

#include "swtjavabufferdrawer.h"
#include "eswt.h"
#include "eswtgraphics.h"
#include "swtcolor.h"
#ifdef _DEBUG
#include "swtdisplay.h" // for debug heap and related macros
#endif //_DEBUG

// Codes for all different bufferable GC operations
static const int OP_DRAWARC               = 1;
static const int OP_DRAWFOCUS             = 2;
static const int OP_DRAWIMAGE             = 3;
static const int OP_DRAWLINE              = 4;
static const int OP_DRAWOVAL              = 5;
static const int OP_DRAWPOINT             = 6;
static const int OP_DRAWPOLYGON           = 7;
static const int OP_DRAWPOLYLINE          = 8;
static const int OP_DRAWRECTANGLE         = 9;
static const int OP_DRAWROUNDRECTANGLE    = 10;
static const int OP_DRAWTEXT              = 11;
static const int OP_FILLARC               = 12;
static const int OP_FILLGRADIENTRECTANGLE = 13;
static const int OP_FILLOVAL              = 14;
static const int OP_FILLPOLYGON           = 15;
static const int OP_FILLRECTANGLE         = 16;
static const int OP_FILLROUNDRECTANGLE    = 17;
static const int OP_SETALPHA              = 18;
static const int OP_SETBACKGROUND         = 19;
static const int OP_SETCLIPPING           = 20;
static const int OP_CANCELCLIPPING        = 21;
static const int OP_SETFONT               = 22;
static const int OP_SETFOREGROUND         = 23;
static const int OP_SETLINESTYLE          = 24;
static const int OP_SETLINEWIDTH          = 25;
static const int OP_SETXORMODE            = 26;
static const int OP_COPYAREA              = 27;
static const int OP_DRAWM2GIMAGE          = 28;
static const int OP_COPYAREATOIMAGE       = 29;
// To be used for debugging, enable writing this flag in the Java code and then
// enable the check in the code below.
//static const int OP_END = 2147483647;


CSwtJavaBufferDrawer::CSwtJavaBufferDrawer(MSwtDisplay& aDisplay) : iDisplay(aDisplay)
{
}


CSwtJavaBufferDrawer::~CSwtJavaBufferDrawer()
{
}

void CSwtJavaBufferDrawer::Draw(MSwtGc* aGc, TInt* aIntParams, TInt aIntCount, HBufC* aStrParams, RWindow* aWindow, const TRect& aDrawRect)
{
    if (!aGc || !aIntParams)
    {
        return;
    }

    TInt i(0);   // Integer parameter array index
    TInt s(0);   // String parameter array index
    const TInt strLength(aStrParams ? aStrParams->Length() : 0);
    while ((i < aIntCount) && (s <= strLength))
    {
        switch (aIntParams[ i++ ])
        {
        case OP_DRAWARC:
        {
            TInt& x          = aIntParams[ i++ ];
            TInt& y          = aIntParams[ i++ ];
            TInt& width      = aIntParams[ i++ ];
            TInt& height     = aIntParams[ i++ ];
            TInt& startAngle = aIntParams[ i++ ];
            TInt& arcAngle   = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->DrawArc(TRect(*point, *size), startAngle, arcAngle);
        }
        break;
        case OP_DRAWFOCUS:
        {
            TInt& x      = aIntParams[ i++ ];
            TInt& y      = aIntParams[ i++ ];
            TInt& width  = aIntParams[ i++ ];
            TInt& height = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->DrawFocusRect(TRect(*point, *size), iDisplay.UiUtils());
        }
        break;
        case OP_DRAWIMAGE:
        {
            MSwtImage* image = reinterpret_cast<MSwtImage*>(aIntParams[ i++ ]);
            TInt& srcX       = aIntParams[ i++ ];
            TInt& srcY       = aIntParams[ i++ ];
            TInt& srcWidth   = aIntParams[ i++ ];
            TInt& srcHeight  = aIntParams[ i++ ];
            TInt& destX      = aIntParams[ i++ ];
            TInt& destY      = aIntParams[ i++ ];
            TInt& destWidth  = aIntParams[ i++ ];
            TInt& destHeight = aIntParams[ i++ ];

            TPoint* srcPos   = reinterpret_cast<TPoint*>(&srcX);
            TSize* srcSize   = reinterpret_cast<TSize*>(&srcWidth);
            TPoint* destPos  = reinterpret_cast<TPoint*>(&destX);
            TSize*  destSize = reinterpret_cast<TSize*>(&destWidth);

            aGc->DrawImage(*image, *srcPos, *srcSize, *destPos, *destSize);
        }
        break;
        case OP_DRAWLINE:
        {
            TInt& x1 = aIntParams[ i++ ];
            TInt& y1 = aIntParams[ i++ ];
            TInt& x2 = aIntParams[ i++ ];
            TInt& y2 = aIntParams[ i++ ];

            TPoint* p1 = reinterpret_cast<TPoint*>(&x1);
            TPoint* p2 = reinterpret_cast<TPoint*>(&x2);

            aGc->DrawLine(*p1, *p2);
        }
        break;
        case OP_DRAWOVAL:
        {
            TInt& x      = aIntParams[ i++ ];
            TInt& y      = aIntParams[ i++ ];
            TInt& width  = aIntParams[ i++ ];
            TInt& height = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->DrawOval(TRect(*point, *size));
        }
        break;
        case OP_DRAWPOINT:
        {
            TInt& x = aIntParams[ i++ ];
            TInt& y = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);

            aGc->DrawPoint(*point);
        }
        break;
        case OP_DRAWPOLYGON:
        {
            TInt& arrayLength = aIntParams[ i++ ];
            aGc->DrawPolygon(reinterpret_cast<TPoint*>(&aIntParams[ i ]), arrayLength/2);
            i += arrayLength;
        }
        break;
        case OP_DRAWPOLYLINE:
        {
            TInt& arrayLength = aIntParams[ i++ ];
            aGc->DrawPolyline(reinterpret_cast<TPoint*>(&aIntParams[ i ]), arrayLength/2);
            i += arrayLength;
        }
        break;
        case OP_DRAWRECTANGLE:
        {
            TInt& x      = aIntParams[ i++ ];
            TInt& y      = aIntParams[ i++ ];
            TInt& width  = aIntParams[ i++ ];
            TInt& height = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->DrawRectangle(TRect(*point, *size));
        }
        break;
        case OP_DRAWROUNDRECTANGLE:
        {
            TInt& x         = aIntParams[ i++ ];
            TInt& y         = aIntParams[ i++ ];
            TInt& width     = aIntParams[ i++ ];
            TInt& height    = aIntParams[ i++ ];
            TInt& arcWidth  = aIntParams[ i++ ];
            TInt& arcHeight = aIntParams[ i++ ];

            TPoint* point  = reinterpret_cast<TPoint*>(&x);
            TSize* size    = reinterpret_cast<TSize*>(&width);
            TSize* arcSize = reinterpret_cast<TSize*>(&arcWidth);

            aGc->DrawRoundRectangle(TRect(*point, *size), *arcSize);
        }
        break;
        case OP_DRAWTEXT:
        {
            TInt& stringLength = aIntParams[ i++ ];
            TInt& x            = aIntParams[ i++ ];
            TInt& y            = aIntParams[ i++ ];
            TInt& flags        = aIntParams[ i++ ];

            const TPoint* position = reinterpret_cast<const TPoint*>(&x);

            ASSERT(strLength -  s >= 0);
#ifdef ESWT_NATIVE_UITHREAD_OWN_HEAP
            RHeap* debugHeap = User::SwitchHeap(static_cast<CSwtDisplay&>(iDisplay).iJavaHeap);
#endif //ESWT_NATIVE_UITHREAD_OWN_HEAP
            TPtr text = aStrParams->Des().MidTPtr(s, stringLength);
#ifdef ESWT_NATIVE_UITHREAD_OWN_HEAP
            User::SwitchHeap(debugHeap);
#endif //ESWT_NATIVE_UITHREAD_OWN_HEAP
            TRAP_IGNORE(aGc->DrawTextL(text, *position, flags));
            s += stringLength;
        }
        break;
        case OP_FILLARC:
        {
            TInt& x          = aIntParams[ i++ ];
            TInt& y          = aIntParams[ i++ ];
            TInt& width      = aIntParams[ i++ ];
            TInt& height     = aIntParams[ i++ ];
            TInt& startAngle = aIntParams[ i++ ];
            TInt& arcAngle   = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->FillArc(TRect(*point, *size), startAngle, arcAngle);
        }
        break;
        case OP_FILLGRADIENTRECTANGLE:
        {
            TInt& x        = aIntParams[ i++ ];
            TInt& y        = aIntParams[ i++ ];
            TInt& width    = aIntParams[ i++ ];
            TInt& height   = aIntParams[ i++ ];
            TInt& vertical = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            TBool invertGradient(EFalse);
            if ((width < 0) || (height < 0))
            {
                invertGradient = ETrue;
            }

            aGc->FillGradientRectangle(TRect(*point, *size), vertical, invertGradient);
        }
        break;
        case OP_FILLOVAL:
        {
            TInt& x      = aIntParams[ i++ ];
            TInt& y      = aIntParams[ i++ ];
            TInt& width  = aIntParams[ i++ ];
            TInt& height = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->FillOval(TRect(*point, *size));
        }
        break;
        case OP_FILLPOLYGON:
        {
            TInt& arrayLength = aIntParams[ i++ ];
            aGc->FillPolygon(reinterpret_cast<TPoint*>(&aIntParams[ i ]), arrayLength/2);
            i += arrayLength;
        }
        break;
        case OP_FILLRECTANGLE:
        {
            TInt& x      = aIntParams[ i++ ];
            TInt& y      = aIntParams[ i++ ];
            TInt& width  = aIntParams[ i++ ];
            TInt& height = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->FillRectangle(TRect(*point, *size));
        }
        break;
        case OP_FILLROUNDRECTANGLE:
        {
            TInt& x         = aIntParams[ i++ ];
            TInt& y         = aIntParams[ i++ ];
            TInt& width     = aIntParams[ i++ ];
            TInt& height    = aIntParams[ i++ ];
            TInt& arcWidth  = aIntParams[ i++ ];
            TInt& arcHeight = aIntParams[ i++ ];

            TPoint* point  = reinterpret_cast<TPoint*>(&x);
            TSize* size    = reinterpret_cast<TSize*>(&width);
            TSize* arcSize = reinterpret_cast<TSize*>(&arcWidth);

            aGc->FillRoundRectangle(TRect(*point, *size), *arcSize);
        }
        break;
        case OP_SETALPHA:
        {
            TInt& alpha = aIntParams[ i++ ];
            aGc->SetAlpha(alpha);
        }
        break;
        case OP_SETBACKGROUND:
        {
            TRgb desiredColor((aIntParams[i] & 0x00ff0000) >> 16,
                              (aIntParams[i] & 0x0000ff00) >> 8,
                              (aIntParams[i] & 0x000000ff),
                              0xff // alpha, fully opaque
                             );
            TRgb deviceColor(
                CSwtColor::RgbValue(*(aGc->BitmapContext().Device()),
                                    desiredColor));
            aGc->SetBrushRgbValue(deviceColor);
            ++i;
        }
        break;
        case OP_SETCLIPPING:
        {
            TInt& x      = aIntParams[ i++ ];
            TInt& y      = aIntParams[ i++ ];
            TInt& width  = aIntParams[ i++ ];
            TInt& height = aIntParams[ i++ ];

            TPoint* point = reinterpret_cast<TPoint*>(&x);
            TSize* size   = reinterpret_cast<TSize*>(&width);

            aGc->SetClippingRect(TRect(*point, *size));
        }
        break;
        case OP_CANCELCLIPPING:
        {
            aGc->CancelClipping();
        }
        break;
        case OP_SETFONT:
        {
            // Font can be NULL
            MSwtFont* font = reinterpret_cast<MSwtFont*>(aIntParams[ i++ ]);
            aGc->SetFont(font);
        }
        break;
        case OP_SETFOREGROUND:
        {
            TRgb desiredColor((aIntParams[i] & 0x00ff0000) >> 16,
                              (aIntParams[i] & 0x0000ff00) >> 8,
                              (aIntParams[i] & 0x000000ff),
                              0xff // alpha, fully opaque
                             );
            TRgb deviceColor(
                CSwtColor::RgbValue(*(aGc->BitmapContext().Device()),
                                    desiredColor));
            aGc->SetPenRgbValue(deviceColor);
            ++i;
        }
        break;
        case OP_SETLINESTYLE:
        {
            TInt& lineStyle = aIntParams[ i++ ];
            TRAP_IGNORE(aGc->SetLineStyleL(static_cast<TSwtLineStyle>(lineStyle)));
        }
        break;
        case OP_SETLINEWIDTH:
        {
            TInt& lineWidth = aIntParams[ i++ ];
            aGc->SetLineWidth(lineWidth);
        }
        break;
        case OP_SETXORMODE:
        {
            TInt& xorMode = aIntParams[ i++ ];
            aGc->SetXORMode(xorMode);
        }
        break;
        case OP_COPYAREA:
        {
            TInt& srcX       = aIntParams[ i++ ];
            TInt& srcY       = aIntParams[ i++ ];
            TInt& width      = aIntParams[ i++ ];
            TInt& height     = aIntParams[ i++ ];
            TInt& destX      = aIntParams[ i++ ];
            TInt& destY      = aIntParams[ i++ ];

            TPoint* pointSrc = reinterpret_cast<TPoint*>(&srcX);
            TSize* size   = reinterpret_cast<TSize*>(&width);
            TPoint* pointDest = reinterpret_cast<TPoint*>(&destX);

            (void)aWindow;    // Just to suppress a potential warning
            (void)aDrawRect;  // Just to suppress a potential warning
#ifdef RD_JAVA_S60_RELEASE_9_2
            aWindow->EndRedraw();
            TInt result = KErrAbort;
            TRAPD(err,result = aGc->FinishOperationL());

            if (err != KErrNone || result != KErrNone)
            {
                CCoeEnv::Static()->WsSession().Flush();
                CCoeEnv::Static()->WsSession().Finish();
            }
            aWindow->BeginRedraw(aDrawRect);
#endif // RD_JAVA_S60_RELEASE_9_2

            aGc->CopyArea(TRect(*pointSrc, *size), *pointDest);
        }
        break;
        case OP_COPYAREATOIMAGE:
        {
            MSwtImage* image = reinterpret_cast<MSwtImage*>(aIntParams[ i++ ]);
            TInt& srcX       = aIntParams[ i++ ];;
            TInt& srcY       = aIntParams[ i++ ];

            TPoint pos(srcX, srcY);

            (void)aWindow;    // Just to suppress a potential warning
            (void)aDrawRect;  // Just to suppress a potential warning
#ifdef RD_JAVA_S60_RELEASE_9_2
            aWindow->EndRedraw();
            TInt result = KErrAbort;
            TRAPD(err,result = aGc->FinishOperationL());

            if (err != KErrNone || result != KErrNone)
            {
                CCoeEnv::Static()->WsSession().Flush();
                CCoeEnv::Static()->WsSession().Finish();
            }
            aWindow->BeginRedraw(aDrawRect);
#endif // RD_JAVA_S60_RELEASE_9_2

            TRAP_IGNORE(aGc->CopyAreaL(*image, pos));
        }
        break;
        case OP_DRAWM2GIMAGE:
        {
            TInt bitmapHandles[4];
            bitmapHandles[0]      = aIntParams[ i++ ];
            bitmapHandles[1]      = aIntParams[ i++ ];
            bitmapHandles[2]      = aIntParams[ i++ ];
            bitmapHandles[3]      = aIntParams[ i++ ];
            TInt& srcX            = aIntParams[ i++ ];
            TInt& srcY            = aIntParams[ i++ ];
            TInt& srcWidth        = aIntParams[ i++ ];
            TInt& srcHeight       = aIntParams[ i++ ];
            TInt& destX           = aIntParams[ i++ ];
            TInt& destY           = aIntParams[ i++ ];
            TInt& destWidth       = aIntParams[ i++ ];
            TInt& destHeight      = aIntParams[ i++ ];
            TInt& useNativeClear  = aIntParams[ i++ ];

            TPoint* srcPos   = reinterpret_cast<TPoint*>(&srcX);
            TSize* srcSize   = reinterpret_cast<TSize*>(&srcWidth);
            TPoint* destPos  = reinterpret_cast<TPoint*>(&destX);
            TSize*  destSize = reinterpret_cast<TSize*>(&destWidth);

            TRAP_IGNORE(aGc->DrawM2GImageL(bitmapHandles, *srcPos, *srcSize, *destPos, *destSize, useNativeClear));
        }
        break;
        default:
            // Abort drawing, buffer is messed up
            ASSERT(EFalse);
            break;
        }
        // If Java code is putting this flag in to separate the parameters for different
        // operations then it can be verified here for debug purposes.
        //ASSERT(aIntParams[i++] == OP_END);
    }
    // All parameters must have been consumed
    ASSERT((i == aIntCount) && (s == strLength));
}