// ---------------------------------------------------------------------------
// Convert device-independent color to device-dependent color.
// ---------------------------------------------------------------------------
//
TInt CPeninputPenTraceDecorator::Rgb2DeviceColor( TDisplayMode aDisplayMode, const TRgb& aColor )
{
    switch( aDisplayMode )
    {
    case EGray2:
    {
        return aColor.Gray2();
    }
    case EGray4:
    {
        return aColor.Gray4();
    }
    case EGray16:
    {
        return aColor.Gray16();
    }
    case EGray256:
    {
        return aColor.Gray256();
    }
    case EColor16:
    {
        return aColor.Color16();
    }
    case EColor256:
    {
        return aColor.Color256();
    }
    case EColor64K:
    {
        return aColor.Color64K();
    }
    case EColor16M:
    {
        return aColor.Color16M();
    }
    case EColor4K:
    {
        return aColor.Color4K();
    }
    case EColor16MU:
    {
        return aColor.Color16MU();
    }
    case EColor16MA:
    {
        return aColor.Color16MA();
    }
    case EColor16MAP:
    {
        return aColor.Color16MAP();
    }
    default:
        return aColor.Internal();
    }
}
/**
Fill a rectangle on the given surface.

@param aSurface		The surface to be filled.
@param aStartPos	Where to place the rectangle.
@param aSize		Size of the rectangle.
@param aColor		The colour to fill it with.
*/
void CSurfaceHelper::FillRectangleL(const TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor)
{
    RSurfaceManager::TInfoBuf infoBuf;
    RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
    User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
    TUint32 color = 0;

    if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
    {
        User::Leave(KErrCorrupt);
    }
    if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
    {
        User::Leave(KErrNotReady);
    }

    switch (info.iPixelFormat)
    {
    case EUidPixelFormatXRGB_8888:
    {
        color = aColor.Color16MU();
#ifdef ALPHA_FIX_24BIT
        color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
#endif
        break;
    }
    case EUidPixelFormatARGB_8888:
    {
        color = aColor.Color16MA();
        break;
    }
    case EUidPixelFormatARGB_8888_PRE:
    {
        color = aColor.Color16MAP();
        break;
    }
    case EUidPixelFormatRGB_565:
    {
        color = aColor.Color64K();
        break;
    }
    default:
    {
        User::Leave(KErrNotSupported);
        break;
    }
    }

    RChunk chunk;
    User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
    CleanupClosePushL(chunk);
    TUint8* surfacePtr = chunk.Base();

    // Check for out of bounds
    TBool validRect = ETrue;
    TInt surfaceWidth = info.iSize.iWidth;
    TInt surfaceHeight = info.iSize.iHeight;

    // Width and Height
    if ((aStartPos.iX + aSize.iWidth) > surfaceWidth)
    {
        validRect = EFalse;
    }

    if ((aStartPos.iY + aSize.iHeight) > surfaceHeight)
    {
        validRect = EFalse;
    }

    // Starting position
    if ((aStartPos.iX < 0) || (aStartPos.iY < 0))
    {
        validRect = EFalse;
    }

    if (!validRect)
    {
        User::Leave(KErrOverflow);
    }

    if (info.iPixelFormat == EUidPixelFormatRGB_565)
    {   //2 bytes per pixel
        if ( info.iSize.iWidth*2>info.iStride)
        {
            User::Leave(KErrOverflow);
        }

        TInt offset;
        User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset));
        TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr + offset);

        // Fill the rectangle
        TInt yPos = aStartPos.iY;
        TInt xPos = aStartPos.iX;
        for (TInt yy = 0; yy < aSize.iHeight; ++yy)
        {
            ptr = reinterpret_cast<TUint16*>(surfacePtr + (yPos*info.iStride));
            for (TInt xx = 0; xx < aSize.iWidth; ++xx)
            {
                ptr[xPos] = color;
                xPos++;
            }
            xPos = aStartPos.iX;
            yPos++;
        }
    }
    else
    {
        if ( info.iSize.iWidth*4>info.iStride)
        {
            User::Leave(KErrOverflow);
        }

        TInt offset;
        User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset));
        TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr + offset);

        // Fill the rectangle
        TInt yPos = aStartPos.iY;
        TInt xPos = aStartPos.iX;
        for (TInt yy = 0; yy < aSize.iHeight; ++yy)
        {
            ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride));
            for (TInt xx = 0; xx < aSize.iWidth; ++xx)
            {
                ptr[xPos] = color;
                xPos++;
            }
            xPos = aStartPos.iX;
            yPos++;
        }
    }
    CleanupStack::PopAndDestroy(&chunk);
}