javauis/lcdui_akn/lcdgr/src/CMIDGraphics.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 15 Sep 2010 12:05:25 +0300
branchRCL_3
changeset 77 7cee158cb8cd
parent 66 2455ef1f5bbc
child 83 26b2b12093af
permissions -rw-r--r--
Revision: v2.2.13 Kit: 201036

/*
* 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 <bitdev.h>
#include <gdi.h>

#ifdef RD_JAVA_NGA_ENABLED
#include <coecntrl.h>
#include <e32cmn.h>
#include <AknLayoutFont.h>
#include <lcdgdrv.h> // for TTransformType
#endif // RD_JAVA_NGA_ENABLED

#include "fbslcdgraphics.h"

#include "CMIDGraphics.h"
#include "CMIDImage.h"

#include "MidProxyMap.h"
#include "LcdGraphics.h"
#include "LcdImage.h"
#include "LcdSurface.h"
#include "LcdBitmapSurface.h"
#include "LcdWindowSurface.h"

#define UnhandAddress(aAddress) (aAddress << 2)

template <class T>
inline T* Unhand(TInt aAddress)
{
    return reinterpret_cast<T*>(UnhandAddress(aAddress));
}

// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
#ifdef RD_JAVA_NGA_ENABLED
CMIDGraphics::CMIDGraphics(
    CMIDProxyMap& aProxyMap, CLcdGraphics* aGraphics,
    TBool aIsImageTarget, MMIDCanvas* aTarget)
        : iCanvasTarget(aTarget)
        , iProxyMap(aProxyMap)
        , iGraphics(aGraphics)
        , iIsImageTarget(aIsImageTarget)
{
}
#else // !RD_JAVA_NGA_ENABLED
CMIDGraphics::CMIDGraphics(
    CMIDProxyMap& aProxyMap, CLcdGraphics* aGraphics, TBool aIsImageTarget)
        : iProxyMap(aProxyMap)
        , iGraphics(aGraphics)
        , iIsImageTarget(aIsImageTarget)
{
}
#endif // RD_JAVA_NGA_ENABLED

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CMIDGraphics::~CMIDGraphics()
{
    delete iGraphics;
}

// ---------------------------------------------------------------------------
// CMIDGraphics::Type()
// ---------------------------------------------------------------------------
//
MMIDComponent::TType CMIDGraphics::Type() const
{
    return EGraphics;
}

// ---------------------------------------------------------------------------
// CMIDGraphics::Dispose()
// ---------------------------------------------------------------------------
//
void CMIDGraphics::Dispose()
{
    delete this;
}

// ---------------------------------------------------------------------------
// From MMIDBufferProcessor
// CMIDGraphics::Processor()
// ---------------------------------------------------------------------------
//
MMIDBufferProcessor* CMIDGraphics::Processor()
{
    return this;
}

// ---------------------------------------------------------------------------
// From MMIDBufferProcessor
// CMIDGraphics::AbortAsync()
// ---------------------------------------------------------------------------
//
void CMIDGraphics::AbortAsync()
{
}

// ---------------------------------------------------------------------------
// From MMIDBufferProcessor
// CMIDGraphics::ProcessL()
// ---------------------------------------------------------------------------
//
#ifdef RD_JAVA_NGA_ENABLED
TBool CMIDGraphics::ProcessL(
    const TMIDBufferOp*& aRead, const TMIDBufferOp* aEnd,
    TInt& /*aCycles*/, java::util::Monitor* /*aMonitor*/)
{
    // Checks if EGL is availabe.
    TBool eglAvailable = EFalse;
    if (iCanvasTarget && iCanvasTarget->IsEglAvailable())
    {
        // Egl is available so bounding boxes of 2D primitives
        // need to be calculated.
        eglAvailable = ETrue;
    }
    
    // Use premultiplied colors in target bitmap if
    // EGL surface is in use or Canvas has video overlay active.
    TBool premultiplied = eglAvailable || 
            (iCanvasTarget && iCanvasTarget->IsVideoOverlayActive());
            
#else // !RD_JAVA_NGA_ENABLED
TBool CMIDGraphics::ProcessL(
    const TMIDBufferOp*& aRead, const TMIDBufferOp* aEnd,
    TInt& /*aCycles*/, TRequestStatus* /*aStatus*/)
{
#endif // RD_JAVA_NGA_ENABLED   
    CLcdGraphics& graphics = *iGraphics;

    graphics.Begin();
    while (aRead < aEnd)
    {
        TInt opCode = aRead->OpCode();

        switch (opCode)
        {
        case EGrOpSetColor:
        {
            const TLcdGrOpSetColor* setColor = (const TLcdGrOpSetColor*)(aRead);
            graphics.SetColor(setColor->iColor);
        }
        break;

        case EGrOpSetStroke:
        {
            const TLcdGrOpSetStrokeStyle* setStroke =
                (const TLcdGrOpSetStrokeStyle*)(aRead);
            graphics.SetStrokeStyle((TStrokeStyle)setStroke->iStyle);
        }
        break;

        case EGrOpSetFont:
        {
            const TLcdGrOpSetFont* setFont = (const TLcdGrOpSetFont*)(aRead);
            graphics.SetFont(setFont->iFont);
        }
        break;

        case EGrOpSetClipRect:
        {
            const TLcdGrOpSetClipRect* clipRect= (const TLcdGrOpSetClipRect*)(aRead);
            graphics.SetClipRect(clipRect->iPosition, clipRect->iSize);
        }
        break;

        case EGrOpTranslate:
        {
            const TLcdGrOpTranslate* translate = (const TLcdGrOpTranslate*)(aRead);
            graphics.Translate(translate->iVector);
        }
        break;

        case EGrOpReset:
        {
            const TLcdGrOpReset* reset = (const TLcdGrOpReset*)(aRead);
            graphics.Reset(reset->iSize);
        }
        break;

        case EGrOpDrawLine:
        {
            ASSERT(aRead->Size() >= 5);
            const TLcdGrOpDrawLine* line = (const TLcdGrOpDrawLine*)(aRead);
            graphics.DrawLine(line->iPoints[0], line->iPoints[1]);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                // Update bounding box
                TRect rect(line->iPoints[0], line->iPoints[1]);
                rect.Normalize();
                // Move br by one pixel to include the end point
                ++rect.iBr.iX;
                ++rect.iBr.iY;
                UpdateRect(rect);
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpDrawRect:
        {
            const TLcdGrOpDrawRect* drawRect = (const TLcdGrOpDrawRect*)(aRead);
            graphics.DrawRect(drawRect->iPosition, drawRect->iSize);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateRect(TRect(
                               drawRect->iPosition,
                               TSize(drawRect->iSize.iWidth + 1, drawRect->iSize.iHeight + 1)));
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpFillRect:
        {
            const TLcdGrOpFillRect* fillRect = (const TLcdGrOpFillRect*)(aRead);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                TRect rect(fillRect->iPosition, fillRect->iSize);
                if (!FillEglSurface(rect, TRgb::Color16MA(graphics.Color())))
                {
                    graphics.FillRect(fillRect->iPosition, fillRect->iSize);
                    UpdateRect(TRect(
                                   fillRect->iPosition,
                                   TSize(fillRect->iSize.iWidth + 1,
                                         fillRect->iSize.iHeight + 1)));
                }
            }
            else
            {
                graphics.FillRect(fillRect->iPosition, fillRect->iSize);
            }
#else // !RD_JAVA_NGA_ENABLED
            graphics.FillRect(fillRect->iPosition, fillRect->iSize);
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpDrawRoundRect:
        {
            const TLcdGrOpDrawRoundRect* drawRoundRect =
                (const TLcdGrOpDrawRoundRect*)(aRead);
            graphics.DrawRoundRect(
                drawRoundRect->iPosition, drawRoundRect->iSize,
                drawRoundRect->iCornerSize);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateRect(TRect(
                               drawRoundRect->iPosition,
                               TSize(drawRoundRect->iSize.iWidth + 1,
                                     drawRoundRect->iSize.iHeight + 1)));
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpFillRoundRect:
        {
            const TLcdGrOpFillRoundRect* fillRoundRect =
                (const TLcdGrOpFillRoundRect*)(aRead);
            graphics.FillRoundRect(
                fillRoundRect->iPosition, fillRoundRect->iSize,
                fillRoundRect->iCornerSize);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateRect(TRect(
                               fillRoundRect->iPosition,
                               TSize(fillRoundRect->iSize.iWidth + 1,
                                     fillRoundRect->iSize.iHeight + 1)));
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpDrawArc:
        {
            const TLcdGrOpDrawArc* drawArc = (const TLcdGrOpDrawArc*)(aRead);
            graphics.DrawArc(
                drawArc->iPosition, drawArc->iSize, drawArc->iStart,
                drawArc->iAngle);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateRect(TRect(
                               drawArc->iPosition,
                               TSize(drawArc->iSize.iWidth + 1, drawArc->iSize.iHeight + 1)));
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpFillArc:
        {
            const TLcdGrOpFillArc* fillArc = (const TLcdGrOpFillArc*)(aRead);
            graphics.FillArc(
                fillArc->iPosition, fillArc->iSize, fillArc->iStart,
                fillArc->iAngle);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateRect(TRect(
                               fillArc->iPosition,
                               TSize(fillArc->iSize.iWidth + 1, fillArc->iSize.iHeight + 1)));
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpDrawText:
        {
            const TLcdGrOpDrawText* drawText = (const TLcdGrOpDrawText*)(aRead);
            TPtrC ptr(&drawText->iText[0], drawText->iLength);
            graphics.DrawText(ptr, drawText->iPoint, drawText->iAnchor);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateTextRect(ptr, drawText->iPoint, drawText->iAnchor);
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpDrawImage:
        {
            const TLcdGrOpDrawImage* drawImage = (const TLcdGrOpDrawImage*)(aRead);
            MMIDComponent* component = Unhand<MMIDComponent>(drawImage->iImage);
            ASSERT(component);
            const CMIDImage& proxy =
                static_cast<const CMIDImage&>(*static_cast<MMIDImage*>(component));
            const CLcdImage& image = proxy.Image();
#ifndef RD_JAVA_NGA_ENABLED
            graphics.DrawImage(image, drawImage->iPoint, drawImage->iAnchor);
#else // RD_JAVA_NGA_ENABLED
            graphics.DrawImage(image, drawImage->iPoint, drawImage->iAnchor, premultiplied);
            if (eglAvailable)
            {
                UpdateRect(CalcDstRect(
                               drawImage->iPoint, image.Size(), ETransNone,
                               (::TAnchor)drawImage->iAnchor));
            }
#endif // !RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpDrawRegion:
        {
            const TLcdGrOpDrawRegion* drawRegion = (const TLcdGrOpDrawRegion*)(aRead);
            MMIDComponent* component = Unhand<MMIDComponent>(drawRegion->iImage);
            ASSERT(component);
            const CMIDImage& proxy =
                static_cast<const CMIDImage&>(*static_cast<MMIDImage*>(component));
            const CLcdImage& image = proxy.Image();
#ifndef RD_JAVA_NGA_ENABLED
            graphics.DrawRegion(
                image, drawRegion->iSrcPosition, drawRegion->iSrcSize,
                drawRegion->iTransform, drawRegion->iDstPoint,
                drawRegion->iAnchor);
#else // RD_JAVA_NGA_ENABLED
            graphics.DrawRegion(
                image, drawRegion->iSrcPosition, drawRegion->iSrcSize,
                drawRegion->iTransform, drawRegion->iDstPoint,
                drawRegion->iAnchor, premultiplied);
            if (eglAvailable)
            {
                UpdateRect(CalcDstRect(drawRegion->iDstPoint, drawRegion->iSrcSize,
                                       (TTransformType)drawRegion->iTransform,
                                       (::TAnchor)drawRegion->iAnchor));
            }
#endif // !RD_JAVA_NGA_ENABLED   
        }
        break;

        case EGrOpCopyArea:
        {
            // NGA: EGrOpCopyArea is not valid for canvas
            const TLcdGrOpCopyArea* copyArea = (const TLcdGrOpCopyArea*)(aRead);
            graphics.CopyArea(copyArea->iSrcPosition, copyArea->iSrcSize,
                              copyArea->iPoint, copyArea->iAnchor);
        }
        break;

        case EGrOpFillTriangle:
        {
            ASSERT(aRead->Size() >= 5);
            const TLcdGrOpFillTriangle* triangle = (const TLcdGrOpFillTriangle*)(aRead);
            graphics.FillTriangle(triangle->iPoints);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateRect(TRect(
                               Min3(triangle->iPoints[ 0 ].iX, triangle->iPoints[ 1 ].iX,
                                    triangle->iPoints[ 2 ].iX),
                               Min3(triangle->iPoints[ 0 ].iY, triangle->iPoints[ 1 ].iY,
                                    triangle->iPoints[ 2 ].iY),
                               Max3(triangle->iPoints[ 0 ].iX, triangle->iPoints[ 1 ].iX,
                                    triangle->iPoints[ 2 ].iX) + 1,
                               Max3(triangle->iPoints[ 0 ].iY, triangle->iPoints[ 1 ].iY,
                                    triangle->iPoints[ 2 ].iY) + 1));
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;
        case EGrOpFlush:
        {
            const TLcdGrOpFlush* flush = (const TLcdGrOpFlush*)(aRead);
            graphics.Flush(flush->iPosition, flush->iSize);
        }
        break;
        case EGrOpDrawBackground:
        {
            const TLcdGrOpDrawBackground* drawBackground =
                (const TLcdGrOpDrawBackground*)(aRead);
            MMIDCanvas* canvas = Unhand<MMIDCanvas>(drawBackground->iCanvas);
            ASSERT(canvas);
            graphics.DrawBackground(canvas, drawBackground->iPosition, drawBackground->iSize);
#ifdef RD_JAVA_NGA_ENABLED
            if (eglAvailable)
            {
                UpdateRect(TRect(drawBackground->iPosition, drawBackground->iSize));
            }
#endif // RD_JAVA_NGA_ENABLED   
        }
        break;
        case EGrOpCopyGraphics:
        {
#ifdef RD_JAVA_NGA_ENABLED
            const TLcdGrOpCopyGraphics* copyGraphics =
                (const TLcdGrOpCopyGraphics*)(aRead);
            MMIDComponent* component = Unhand<MMIDComponent>(copyGraphics->iSrcGraphics);
            ASSERT(component);
            CMIDGraphics* proxy =
                static_cast<CMIDGraphics*>(static_cast<MMIDGraphics*>(component));
            CLcdGraphics* srcGraphics = proxy->iGraphics;
            proxy->UpdateOffScreenBitmapL(ETrue);
            graphics.CopyGraphics(srcGraphics);

#endif // RD_JAVA_NGA_ENABLED   
        }
        break;
        default:
#ifdef _TRACE
            RDebug::Print(_L("CMIDGraphics::ProcessL - ignoring unknown opcode %d"), opCode);
#endif
            break;
        }
        aRead += aRead->Size();
    }
    graphics.End();
    return EFalse;
}


// ---------------------------------------------------------------------------
// CMIDGraphics::DrawPixels()
// ---------------------------------------------------------------------------
//
TInt CMIDGraphics::DrawPixels
(
    TInt    aType,          // pixel data type
    TUint8* aAddress,       // pixel data array
    TInt    aLength,        // pixel array length - bytes
    TInt    aScanLength,    // always positive - vertical reflection handled by point/size
    TBool   aAlpha,         // true if pixel data contains alpha
    const TRect& aRect,
    TInt    aTransform      // transform to apply
)
{
    TInt err;
    TSize size(aRect.Size());
    iGraphics->Begin();

    TBool premultiplied(EFalse);
#ifdef RD_JAVA_NGA_ENABLED
    if (IsEglAvailable())
    {
        premultiplied = ETrue;
        UpdateRect(aRect);
    }
    
    // Video overlay support
    if (iCanvasTarget && iCanvasTarget->IsVideoOverlayActive())
    {
        premultiplied = ETrue;
    }
#endif

    err = iGraphics->DrawPixels(aType, aAddress, aLength, aScanLength,
                                aAlpha, aRect.iTl, size, aTransform, premultiplied);
    iGraphics->End();
    return err;
}

// ---------------------------------------------------------------------------
// CMIDGraphics::DisplayColor()
// Maps a color provided as 32bit rgb triple to the closest color representable
// in the target devices display mode. returns the result as a 32bit rgb triple.
// ---------------------------------------------------------------------------
//
TUint32 CMIDGraphics::DisplayColor(TUint32 aRGB32)
{
    return iGraphics->QuantizeColor(aRGB32);
}

// ---------------------------------------------------------------------------
// CMIDGraphics::Bitmap()
// Returns a pointer to the back buffer bitmap in use by the graphics object.
// May return NULL.
// ---------------------------------------------------------------------------
//
CFbsBitmap* CMIDGraphics::Bitmap() const
{
    CLcdSurface* surface = iGraphics->Surface();
    if (surface->Type() == CLcdSurface::EBitmapSurface)
    {
        CLcdBitmapSurface* bitmapSurface = (CLcdBitmapSurface*)surface;
        return bitmapSurface->Bitmap();
    }
    return NULL;
}

// ---------------------------------------------------------------------------
// CMIDGraphics::Window()
// ---------------------------------------------------------------------------
//
RWindow* CMIDGraphics::Window() const
{
    CLcdSurface* surface = iGraphics->Surface();
    if (surface->Type() == CLcdSurface::EWindowSurface)
    {
        CLcdWindowSurface* windowSurface = (CLcdWindowSurface*)surface;
        return windowSurface->Window();
    }
    return NULL;
}

// ---------------------------------------------------------------------------
// CMIDGraphics::ViewPort()
// @return drawing surface viewport rectangle.
// ---------------------------------------------------------------------------
//
TRect CMIDGraphics::ViewPort() const
{
    return iGraphics->Surface()->Bounds();
}

// ---------------------------------------------------------------------------
// CMIDGraphics::IsImageTarget()
// @return ETrue for mutable off-screen images (not for canvas/GameCanvas framebuffer)
// or EFalse for canvas/GameCanvas framebuffer
// ---------------------------------------------------------------------------
//
TBool CMIDGraphics::IsImageTarget() const
{
    return iIsImageTarget;
}

#ifdef RD_JAVA_NGA_ENABLED

// ---------------------------------------------------------------------------
// From MMIDComponentNgaExtension
// CMIDGraphics::UpdateEglContent()
// ---------------------------------------------------------------------------
//
void CMIDGraphics::UpdateEglContent()
{
    if (iCanvasTarget)
    {
        iCanvasTarget->UpdateEglContent();
    }
}

// ---------------------------------------------------------------------------
// From MMIDComponentNgaExtension
// CMIDGraphics::IsEglAvailable()
// ---------------------------------------------------------------------------
//
TBool CMIDGraphics::IsEglAvailable() const
{
    return (iCanvasTarget ? iCanvasTarget->IsEglAvailable() : EFalse);
}

// ---------------------------------------------------------------------------
// From MMIDComponentNgaExtension
// CMIDGraphics::BindEglSurface()
// ---------------------------------------------------------------------------
//
EGLSurface CMIDGraphics::BindEglSurface()
{
    return (iCanvasTarget ? iCanvasTarget->BindEglSurface() : EGL_NO_SURFACE);
}

// ---------------------------------------------------------------------------
// From MMIDComponentNgaExtension
// CMIDGraphics::ReleaseEglSurface()
// ---------------------------------------------------------------------------
//
void CMIDGraphics::ReleaseEglSurface()
{
    if (iCanvasTarget)
    {
        iCanvasTarget->ReleaseEglSurface();
    }
}

// ---------------------------------------------------------------------------
// From MMIDComponentNgaExtension
// CMIDGraphics::UpdateOffScreenBitmapL()
// ---------------------------------------------------------------------------
//
void CMIDGraphics::UpdateOffScreenBitmapL(TBool aForced)
{
    if (iCanvasTarget)
    {
        iCanvasTarget->UpdateOffScreenBitmapL(aForced);
    }
}

// ---------------------------------------------------------------------------
// From MMIDComponentNgaExtension
// CMIDGraphics::FillEglSurface()
// ---------------------------------------------------------------------------
//
TBool CMIDGraphics::FillEglSurface(const TRect& aRect, const TRgb& aColor)
{
    if (iCanvasTarget)
    {
        TRect rect(aRect);
        rect.Move(iGraphics->CurrentOriginInTargetCoords());
        rect.Intersection(iGraphics->CurrentClipRectInTargetCoords());
        TSize canvasSize = iCanvasTarget->Control().Size();
        rect.Intersection(TRect(iCanvasTarget->Control().Size()));
        return iCanvasTarget->FillEglSurface(rect, aColor);
    }
    return EFalse;
}


// ---------------------------------------------------------------------------
// CMIDGraphics::CanvasTargetSize()
// ---------------------------------------------------------------------------
//
TSize CMIDGraphics::CanvasTargetSize() const
{
    if (iCanvasTarget)
    {
        return iCanvasTarget->ContentSize();
    }
    else
    {
        return TSize();
    }
}

// ---------------------------------------------------------------------------
// CMIDGraphics::GetTargetCanvas()
// ---------------------------------------------------------------------------
//
MMIDCanvas* CMIDGraphics::GetTargetCanvas() const
{
    return iCanvasTarget;
}

// ---------------------------------------------------------------------------
// CMIDGraphics::UpdateRect()
// Merges aRect to member TRects that are used for tracking the updated canvas
// area. Current coordinate translation and clip rect are taken into account.
// ---------------------------------------------------------------------------
//
void CMIDGraphics::UpdateRect(const TRect& aRect)
{
    // Translate rect to target (=canvas) coordinates
    TRect rect(aRect);
    rect.Move(iGraphics->CurrentOriginInTargetCoords());

    // Clip with current clip rect and canvas bounds
    rect.Intersection(iGraphics->CurrentClipRectInTargetCoords());

    iCanvasTarget->UpdateRect(rect);
}

// ---------------------------------------------------------------------------
// CMIDGraphics::UpdateTextRect()
// Calculates bounding box for text.
// ---------------------------------------------------------------------------
//
void CMIDGraphics::UpdateTextRect(TPtrC& aTextPtr, const TPoint& aP, TInt aAnchor)
{
    CFont* font = iGraphics->CurrentFont();

    // Create a bounding box for the text
    // TextWidthInPixels() seems to return few pixels too small value.
    // Width of the zero char is added to be sure that bouding box is
    // long enough.
    TRect boundingBox(aP, TSize(font->TextWidthInPixels(aTextPtr) +
                                font->WidthZeroInPixels(), 0));
    const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull(font);

    if (layoutFont)
    {
        boundingBox.SetHeight(layoutFont->TextPaneHeight());
    }
    else
    {
        boundingBox.SetHeight(font->FontMaxHeight());
    }

    // Moving the bounding box according to the anchor. The EAnchorTop is
    // default vertically and the EAnchorLeft is default horizontally
    if (aAnchor & EAnchorBaseline)
    {
        boundingBox.Move(0, -font->FontMaxAscent());
    }
    else if (aAnchor & EAnchorBottom)
    {
        boundingBox.Move(0, -boundingBox.Height());
    }

    if (aAnchor & EAnchorHCenter)
    {
        boundingBox.Move(-(boundingBox.Width() / 2), 0);
    }
    else if (aAnchor & EAnchorRight)
    {
        boundingBox.Move(-boundingBox.Width(), 0);
    }
    UpdateRect(boundingBox);
}

#endif // RD_JAVA_NGA_ENABLED