diff -r f5050f1da672 -r 04becd199f91 javauis/lcdui_akn/lcdgd/src/lcd32bpp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/lcdui_akn/lcdgd/src/lcd32bpp.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,846 @@ +/* +* 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 +#include + +#include "lcd32bpp.h" +#include "lcdgdrvutil.h" +#include "lcdtransform.h" +#include "lcdbitblt.h" + +LOCAL_C void FillTriangle32Bpp32 +( + const TAcceleratedBitmapInfo* aBitmap, + const TPoint aPoints[], + TUint32 aColor32Bpp, + const TRect& aClipRect +) +{ + TRect clipRect(aBitmap->iSize); + clipRect.Intersection(aClipRect); + const TInt clipX1 = clipRect.iTl.iX; + const TInt clipY1 = clipRect.iTl.iY; + const TInt clipX2 = clipRect.iBr.iX; + const TInt clipY2 = clipRect.iBr.iY; + + TInt i; + + TInt ymin=0; + TInt ymax=0; + TInt xmin=0; + TInt xmax=0; + + for (i=1; i<3; i++) + { + if (aPoints[i].iX < aPoints[xmin].iX) xmin = i; + if (aPoints[i].iX > aPoints[xmax].iX) xmax = i; + if (aPoints[i].iY < aPoints[ymin].iY) ymin = i; + if (aPoints[i].iY > aPoints[ymax].iY) ymax = i; + } + const TInt ymid = 3 - (ymax + ymin); + + + TEdge edges[3]; + + // + // Long edge top to bottom. + // + edges[0].iDy = aPoints[ymax].iY - aPoints[ymin].iY; + if (edges[0].iDy == 0) + { + return; + } + edges[0].iDx = aPoints[ymax].iX - aPoints[ymin].iX; + edges[0].iX = aPoints[ymin].iX; + edges[0].iF = 0; + edges[0].iD = edges[0].iDy; + edges[0].iDe = Sign(edges[0].iDx); + Increment(edges[0].iIx, edges[0].iIf, edges[0].iDx, edges[0].iDy); + ASSERT(edges[0].iDy >= 0); + + // + // Short top edge, or flat top + // + edges[1].iDx = aPoints[ymid].iX - aPoints[ymin].iX; + edges[1].iDy = aPoints[ymid].iY - aPoints[ymin].iY; + edges[1].iX = aPoints[ymin].iX; + edges[1].iF = 0; + edges[1].iD = edges[1].iDy; + edges[1].iDe = Sign(edges[1].iDx); + ASSERT(edges[1].iDy >= 0); + + // + // Short bottom edge or flat bottom + // + edges[2].iDx = aPoints[ymax].iX - aPoints[ymid].iX; + edges[2].iDy = aPoints[ymax].iY - aPoints[ymid].iY; + edges[2].iX = aPoints[ymid].iX; + edges[2].iF = 0; + edges[2].iD = edges[2].iDy; + edges[2].iDe = Sign(edges[2].iDx); + ASSERT(edges[2].iDy >= 0); + + const TBool flatTop = (edges[1].iDy == 0); + const TBool flatBottom = (edges[2].iDy == 0); + + // + // work out whether long edge is left most or right most. + // + // compare slopes of long edge and top edge. + // + TBool longEdgeRight; + if (flatTop) + { + longEdgeRight = (aPoints[ymid].iX < aPoints[ymin].iX); + } + else + { + longEdgeRight = (edges[0].iDx*edges[1].iDy) > (edges[1].iDx*edges[0].iDy); + } + + TInt y = aPoints[ymin].iY; + TInt yEnd = Min(aPoints[ymid].iY, clipY2); + TEdge* el = NULL; + TEdge* er = NULL; + TInt m; // number of lines to skip + TInt x1; // start of clipped scan (inclusive) + TInt x2; // end of clipped scan (exclusive), exclusive overrides inclusive + + TInt eliX; // Locals used to speed access to edge information in loops. + TInt eliF; + TInt eliD; + TInt eriX; + TInt eriF; + TInt eriD; + + TUint8* base = aBitmap->iAddress; + TUint8* line = NULL; + TInt linePitch = aBitmap->iLinePitch; + TUint32* dst; + TUint32* end; + TUint32 color32 = (TUint32)aColor32Bpp; + + // + // render top half. + // + if (!flatTop) + { + Increment(edges[1].iIx, edges[1].iIf, edges[1].iDx, edges[1].iDy); + if (longEdgeRight) + { + er = &edges[0]; + el = &edges[1]; + } + else + { + er = &edges[1]; + el = &edges[0]; + } + eliX = el->iX; + eliF = el->iF; + eliD = el->iD; + eriX = er->iX; + eriF = er->iF; + eriD = er->iD; + + // + // Clip to top of clip rect. + // + if (y < clipY1) + { + TInt yTop = Min(clipY1, yEnd); + + m = (yTop - y); + + eliX += m*el->iIx; + eliF += m*el->iIf; + while (eliF > 0) + { + eliX ++; + eliF -= eliD; + } + + eriX += m*er->iIx; + eriF += m*er->iIf; + while (eriF > 0) + { + eriX ++; + eriF -= eriD; + } + + y = yTop; + } + + ASSERT(((1 - eriD) <= eriF) && (eriF <= 0)); + ASSERT(((1 - eliD) <= eliF) && (eliF <= 0)); + +#ifdef PLOT_TOP_VERTEX + // special case top vertex - can produce pimple so prob best avoided. + if (aClipRect.Contains(aPoints[ymin])) + { + line = base + aPoints[ymin].iY*linePitch; + ((TUint32*)line)[aPoints[ymin].iX] = color32; + } +#endif + + line = base + y*linePitch; + for (; y clipX1)) + { + x1 = Max(eliX, clipX1); // inclusive (ceil) + x2 = Min(eriX, clipX2); // exclusive (floor) + + dst = (TUint32*)(line + x1*sizeof(TUint32)); + end = (TUint32*)(line + x2*sizeof(TUint32)); + while (dst < end) + { + *dst++ = color32; + } + } + + eliX += el->iIx; + eliF += el->iIf; + if (eliF > 0) + { + eliX ++; + eliF -= eliD; + } + + eriX += er->iIx; + eriF += er->iIf; + if (eriF > 0) + { + eriX ++; + eriF -= eriD; + } + + line += linePitch; + } + + el->iX = eliX; + el->iF = eliF; + el->iD = eliD; + er->iX = eriX; + er->iF = eriF; + er->iD = eriD; + } + + if (!flatBottom) + { + Increment(edges[2].iIx, edges[2].iIf, edges[2].iDx, edges[2].iDy); + if (longEdgeRight) + { + // initialize short left edge + er = &edges[0]; + el = &edges[2]; + } + else + { + // initialize short right edge + er = &edges[2]; + el = &edges[0]; + } + eliX = el->iX; + eliF = el->iF; + eliD = el->iD; + eriX = er->iX; + eriF = er->iF; + eriD = er->iD; + + // + // clip to top edge of clip rect. + // + // + // Clip to top of clip rect. + // + if (y < clipY1) + { + m = (clipY1 - y); + + eliX += m*el->iIx; + eliF += m*el->iIf; + while (eliF > 0) + { + eliX ++; + eliF -= eliD; + } + + eriX += m*er->iIx; + eriF += m*er->iIf; + while (eriF > 0) + { + eriX ++; + eriF -= eriD; + } + y = clipY1; + } + + line = base + y*linePitch; + yEnd = Min(aPoints[ymax].iY, clipY2); + for (; y clipX1)) + { + x1 = Max(eliX, clipX1); // inclusive (ceil) + x2 = Min(eriX, clipX2); // exclusive (floor) + + dst = (TUint32*)(line + x1*sizeof(TUint32)); + end = (TUint32*)(line + x2*sizeof(TUint32)); + while (dst < end) + { + *dst++ = color32; + } + } + + eliX += el->iIx; + eliF += el->iIf; + if (eliF > 0) + { + eliX ++; + eliF -= eliD; + } + + eriX += er->iIx; + eriF += er->iIf; + if (eriF > 0) + { + eriX ++; + eriF -= eriD; + } + + line += linePitch; + } + + el->iX = eliX; + el->iF = eliF; + el->iD = eliD; + er->iX = eriX; + er->iF = eriF; + er->iD = eriD; + } +} + +LOCAL_C void FillTriangle32Bpp64 +( + const TAcceleratedBitmapInfo* aBitmap, + const TPoint aPoints[], + TUint32 aColor32Bpp, + const TRect& aClipRect +) +{ + TRect clipRect(aBitmap->iSize); + clipRect.Intersection(aClipRect); + const TInt64 clipX1 = (TInt64)(clipRect.iTl.iX); + const TInt64 clipY1 = (TInt64)(clipRect.iTl.iY); + const TInt64 clipX2 = (TInt64)(clipRect.iBr.iX); + const TInt64 clipY2 = (TInt64)(clipRect.iBr.iY); + + TInt i; + + TInt ymin=0; + TInt ymax=0; + TInt xmin=0; + TInt xmax=0; + + for (i=1; i<3; i++) + { + if (aPoints[i].iX < aPoints[xmin].iX) xmin = i; + if (aPoints[i].iX > aPoints[xmax].iX) xmax = i; + if (aPoints[i].iY < aPoints[ymin].iY) ymin = i; + if (aPoints[i].iY > aPoints[ymax].iY) ymax = i; + } + const TInt ymid = 3 - (ymax + ymin); + + // const TInt64 minX = aPoints[xmin].iX; + // const TInt64 maxX = aPoints[xmax].iX; + + TEdge64 edges[3]; + + // + // Long edge top to bottom. + // + edges[0].iDy = (TInt64)(aPoints[ymax].iY) - (TInt64)(aPoints[ymin].iY); + if (edges[0].iDy == 0) + { + return; + } + edges[0].iDx = (TInt64)(aPoints[ymax].iX) - (TInt64)(aPoints[ymin].iX); + edges[0].iX = (TInt64)(aPoints[ymin].iX); + edges[0].iF = 0; + edges[0].iD = edges[0].iDy; + edges[0].iDe = Sign(edges[0].iDx); + Increment(edges[0].iIx, edges[0].iIf, edges[0].iDx, edges[0].iDy); + ASSERT(edges[0].iDy >= 0); + + // + // Short top edge, or flat top + // + edges[1].iDx = (TInt64)(aPoints[ymid].iX) - (TInt64)(aPoints[ymin].iX); + edges[1].iDy = (TInt64)(aPoints[ymid].iY) - (TInt64)(aPoints[ymin].iY); + edges[1].iX = (TInt64)(aPoints[ymin].iX); + edges[1].iF = 0; + edges[1].iD = edges[1].iDy; + edges[1].iDe = Sign(edges[1].iDx); + ASSERT(edges[1].iDy >= 0); + + // + // Short bottom edge or flat bottom + // + edges[2].iDx = (TInt64)(aPoints[ymax].iX) - (TInt64)(aPoints[ymid].iX); + edges[2].iDy = (TInt64)(aPoints[ymax].iY) - (TInt64)(aPoints[ymid].iY); + edges[2].iX = (TInt64)(aPoints[ymid].iX); + edges[2].iF = 0; + edges[2].iD = edges[2].iDy; + edges[2].iDe = Sign(edges[2].iDx); + ASSERT(edges[2].iDy >= 0); + + const TBool flatTop = (edges[1].iDy == 0); + const TBool flatBottom = (edges[2].iDy == 0); + + // + // work out whether long edge is left most or right most. + // + // compare slopes of long edge and top edge. + // + TBool longEdgeRight; + if (flatTop) + { + longEdgeRight = (aPoints[ymid].iX < aPoints[ymin].iX); + } + else + { + longEdgeRight = (edges[0].iDx*edges[1].iDy) > (edges[1].iDx*edges[0].iDy); + } + + TInt64 y = (TInt64)aPoints[ymin].iY; + TInt64 yEnd = Min(aPoints[ymid].iY, clipY2); + TEdge64* el = NULL; + TEdge64* er = NULL; + TInt64 m; // number of lines to skip + TInt64 x1; // start of clipped scan (inclusive) + TInt64 x2; // end of clipped scan (exclusive), exclusive overrides inclusive + + TInt64 eliX; // Locals used to speed access to edge information in loops. + TInt64 eliF; + TInt64 eliD; + TInt64 eriX; + TInt64 eriF; + TInt64 eriD; + + TUint8* base = aBitmap->iAddress; + TUint8* line = NULL; + TInt linePitch = aBitmap->iLinePitch; + TUint32* dst; + TUint32* end; + TUint32 color32 = (TUint32)aColor32Bpp; + + // + // render top half. + // + if (!flatTop) + { + Increment(edges[1].iIx, edges[1].iIf, edges[1].iDx, edges[1].iDy); + if (longEdgeRight) + { + er = &edges[0]; + el = &edges[1]; + } + else + { + er = &edges[1]; + el = &edges[0]; + } + eliX = el->iX; + eliF = el->iF; + eliD = el->iD; + eriX = er->iX; + eriF = er->iF; + eriD = er->iD; + + // + // Clip to top of clip rect. + // + if (y < clipY1) + { + TInt64 yTop = Min(clipY1, yEnd); + + m = (yTop - y); + + double leftSlope = (double)(el->iDx)/(double)(el->iDy); + + eliX += (leftSlope * ((double)m)); + + double rightSlope = (double)(er->iDx)/(double)(er->iDy); + + eriX += (rightSlope * ((double)m)); + y = yTop; + } + + ASSERT(((1 - eriD) <= eriF) && (eriF <= 0)); + ASSERT(((1 - eliD) <= eliF) && (eliF <= 0)); + +#ifdef PLOT_TOP_VERTEX + // special case top vertex - can produce pimple so prob best avoided. + if (aClipRect.Contains(aPoints[ymin])) + { + line = base + aPoints[ymin].iY*linePitch; + ((TUint32*)line)[aPoints[ymin].iX] = color32; + } +#endif + + line = base + y*linePitch; + for (; y clipX1)) + { + x1 = Max(eliX, clipX1); // inclusive (ceil) + x2 = Min(eriX, clipX2); // exclusive (floor) + + dst = (TUint32*)(line + x1*sizeof(TUint32)); + end = (TUint32*)(line + x2*sizeof(TUint32)); + while (dst < end) + { + *dst++ = color32; + } + } + eliX += el->iIx; + eliF += el->iIf; + if (eliF > 0) + { + eliX ++; + eliF -= eliD; + } + + eriX += er->iIx; + eriF += er->iIf; + if (eriF > 0) + { + eriX ++; + eriF -= eriD; + } + + line += linePitch; + } + + el->iX = eliX; + el->iF = eliF; + el->iD = eliD; + er->iX = eriX; + er->iF = eriF; + er->iD = eriD; + } + + if (!flatBottom) + { + Increment(edges[2].iIx, edges[2].iIf, edges[2].iDx, edges[2].iDy); + if (longEdgeRight) + { + // initialize short left edge + er = &edges[0]; + el = &edges[2]; + } + else + { + // initialize short right edge + er = &edges[2]; + el = &edges[0]; + } + eliX = el->iX; + eliF = el->iF; + eliD = el->iD; + eriX = er->iX; + eriF = er->iF; + eriD = er->iD; + + // + // clip to top edge of clip rect. + // + // + // Clip to top of clip rect. + // + if (y < clipY1) + { + m = (clipY1 - y); + + double leftSlope = (double)(el->iDx)/(double)(el->iDy); + + eliX += (leftSlope * m); + + double rightSlope = (double)(er->iDx)/(double)(er->iDy); + + eriX += (rightSlope * m); + + y = clipY1; + } + + line = base + y*linePitch; + yEnd = Min(aPoints[ymax].iY, clipY2); + for (; y clipX1)) + { + x1 = Max(eliX, clipX1); // inclusive (ceil) + x2 = Min(eriX, clipX2); // exclusive (floor) + + dst = (TUint32*)(line + x1*sizeof(TUint32)); + end = (TUint32*)(line + x2*sizeof(TUint32)); + while (dst < end) + { + *dst++ = color32; + } + } + + eliX += el->iIx; + eliF += el->iIf; + if (eliF > 0) + { + eliX ++; + eliF -= eliD; + } + + eriX += er->iIx; + eriF += er->iIf; + if (eriF > 0) + { + eriX ++; + eriF -= eriD; + } + + line += linePitch; + } + + el->iX = eliX; + el->iF = eliF; + el->iD = eliD; + er->iX = eriX; + er->iF = eriF; + er->iD = eriD; + } +} + +LOCAL_C TBool IsPathologicalTriangle(const TPoint aPoints[3]) +{ + TInt minX = aPoints[0].iX; + TInt maxX = aPoints[0].iX; + TInt minY = aPoints[0].iY; + TInt maxY = aPoints[0].iY; + + for (TInt i = 1; i <= 2; i++) + { + TInt x = aPoints[i].iX; + TInt y = aPoints[i].iY; + + if (x < minX) + { + minX = x; + } + if (x > maxX) + { + maxX = x; + } + if (y < minY) + { + minY = y; + } + if (y > maxY) + { + maxY = y; + } + } + if (minX < 0) + { + if (maxX >= (0x7FFFFFFF + minX)) + { + return ETrue; + } + if (-minX > 0xFFFFF) + { + return ETrue; + } + } + if (maxX > 0) + { + if ((maxX == 0x7FFFFFFF) && (minX == 0)) + { + return ETrue; + } + if (maxX > 0xFFFFF) + { + return ETrue; + } + } + if (minY < 0) + { + if (maxY >= (0x7FFFFFFF + minY)) + { + return ETrue; + } + if (-minY > 0xFFFFF) + { + return ETrue; + } + } + if (minY > 0) + { + if ((maxY == 0x7FFFFFFF) && (minX == 0)) + { + return ETrue; + } + if (minY > 0xFFFFF) + { + return ETrue; + } + } + return EFalse; +} + +extern void FillTriangle32Bpp +( + const TAcceleratedBitmapInfo* aBitmap, + const TPoint aPoints[], + TUint32 aColor32Bpp, + const TRect& aClipRect +) +{ + if (!IsPathologicalTriangle(aPoints)) + { + FillTriangle32Bpp32(aBitmap, aPoints, aColor32Bpp, aClipRect); + } + else + { + FillTriangle32Bpp64(aBitmap, aPoints, aColor32Bpp, aClipRect); + } +} + +LOCAL_C void BlitLineThirtyTwoBppSimple +( + TUint8* aDstAddress, + TInt aWidth, + TUint8* aColorAddress, + TInt DEBUG_ONLY(aColorPixelPitch) +) +{ + ASSERT(aColorPixelPitch == sizeof(TUint32)); + Mem::Move(aDstAddress, aColorAddress, aWidth * sizeof(TUint32)); +} + + +extern void BitBltThirtyTwoBppSimple +( + const TAcceleratedBitmapInfo* aDstColorBitmap, + const TAcceleratedBitmapInfo* /*aDstAlphaBitmap*/, + const TRect& aDstRect, + const TAcceleratedBitmapInfo* aSrcColorBitmap, + const TAcceleratedBitmapInfo* /*aSrcAlphaBitmap*/, + const TLcdTransform& aTransform +) +{ + // + // Translation or translation & vertical reflection case. + // + ASSERT(aTransform.iDuDx == 1); + ASSERT(aTransform.iDuDy == 0); + ASSERT(aTransform.iDvDx == 0); + ASSERT(aTransform.iDvDy == 1 || aTransform.iDvDy == -1); + + GenericBlit(aDstColorBitmap, aDstRect, aSrcColorBitmap, aTransform, + BlitLineThirtyTwoBppSimple); +} + + +LOCAL_C void BlitLineThirtyTwoBpp +( + TUint8* aDstAddress, + TInt aWidth, + TUint8* aColorAddress, + TInt aColorPixelPitch +) +{ + TUint32* dst = (TUint32*)aDstAddress; + TUint32* end = dst + aWidth; + + TUint8* colorAddr = aColorAddress; + while (dst < end) + { + *dst++ = *(TUint32*)colorAddr; + colorAddr += aColorPixelPitch; + } +} + + +extern void BitBltThirtyTwoBpp +( + const TAcceleratedBitmapInfo* aDstColorBitmap, + const TAcceleratedBitmapInfo* /*aDstAlphaBitmap*/, + const TRect& aDstRect, + const TAcceleratedBitmapInfo* aSrcColorBitmap, + const TAcceleratedBitmapInfo* /*aSrcAlphaBitmap*/, + const TLcdTransform& aTransform +) +{ + GenericBlit(aDstColorBitmap, aDstRect, aSrcColorBitmap, aTransform, + BlitLineThirtyTwoBpp); +} + +extern void BitBltThirtyTwoBppEightBpp +( + const TAcceleratedBitmapInfo* aDstColorBitmap, + const TAcceleratedBitmapInfo* aDstAlphaBitmap, + const TRect& aDstRect, + const TAcceleratedBitmapInfo* aSrcColorBitmap, + const TAcceleratedBitmapInfo* aSrcAlphaBitmap, + const TLcdTransform& aTransform +) +{ + BitBltThirtyTwoBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform); + BitBltEightBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform); +} + +extern void BitBltThirtyTwoBppOneBpp +( + const TAcceleratedBitmapInfo* aDstColorBitmap, + const TAcceleratedBitmapInfo* aDstAlphaBitmap, + const TRect& aDstRect, + const TAcceleratedBitmapInfo* aSrcColorBitmap, + const TAcceleratedBitmapInfo* aSrcAlphaBitmap, + const TLcdTransform& aTransform +) +{ + BitBltThirtyTwoBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform); + BitBltOneBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform); +} + +extern void BitBltThirtyTwoBppThirtyTwoBpp +( + const TAcceleratedBitmapInfo* aDstColorBitmap, + const TAcceleratedBitmapInfo* aDstAlphaBitmap, + const TRect& aDstRect, + const TAcceleratedBitmapInfo* aSrcColorBitmap, + const TAcceleratedBitmapInfo* aSrcAlphaBitmap, + const TLcdTransform& aTransform +) +{ + BitBltThirtyTwoBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform); + BitBltThirtyTwoBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform); +}