diff -r f5050f1da672 -r 04becd199f91 javauis/lcdui_akn/lcdgd/src/lcdgdev.cpp --- /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 +#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 aSrcTransparency). + */ +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<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 aSrcColorBitmap,aSrcAlphaBitmap + * to aDstColorBitmap,aDstAlphaBitmap. + * 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 + * aSrcTransform. + */ +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<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 aRect + */ +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 aRect with color aRGB + */ +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