javauis/lcdui_akn/lcdgd/src/lcd16bpp.cpp
branchRCL_3
changeset 19 04becd199f91
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <e32std.h>
       
    19 #include <gdi.h>
       
    20 #include <graphicsaccelerator.h>
       
    21 #include <j2me/jdebug.h>
       
    22 
       
    23 #include "lcdgdrvif.h"
       
    24 #include "lcdbitblt.h"
       
    25 #include "lcd16bpp.h"
       
    26 #include "lcdtransform.h"
       
    27 #include "lcdgdrvutil.h"
       
    28 
       
    29 #ifdef _DEBUG
       
    30 inline TInt BPP(const TAcceleratedBitmapInfo* aBitmap)
       
    31 {
       
    32     if (aBitmap->iDisplayMode == EColor16M)
       
    33     {
       
    34         return 24;
       
    35     }
       
    36     return (1<<aBitmap->iPixelShift);
       
    37 }
       
    38 
       
    39 inline TBool VALID(const TAcceleratedBitmapInfo* aDstBitmap, const TAcceleratedBitmapInfo* aSrcBitmap)
       
    40 {
       
    41     if (aDstBitmap && aSrcBitmap)
       
    42     {
       
    43         return (NULL != aDstBitmap->iAddress) &&
       
    44                (NULL != aSrcBitmap->iAddress) &&
       
    45                (aDstBitmap->iDisplayMode == aSrcBitmap->iDisplayMode) &&
       
    46                (BPP(aDstBitmap)==16);
       
    47     }
       
    48     return EFalse;
       
    49 }
       
    50 #endif
       
    51 
       
    52 
       
    53 extern void DrawRegion16Bpp1BppTo16BppOpaque
       
    54 (
       
    55     const TAcceleratedBitmapInfo* aDstColorBitmap,      // must be 16bpp mode
       
    56     const TAcceleratedBitmapInfo* /*aDstAlphaBitmap*/,
       
    57     const TRect&                  aDstRect,             // must be clipped to destination
       
    58     const TAcceleratedBitmapInfo* aSrcColorBitmap,      // must match aDstColorBitmap mode
       
    59     const TAcceleratedBitmapInfo* aSrcAlphaBitmap,      // must be EGray2
       
    60     const TLcdTransform&          aTransform            // includes anchor
       
    61 )
       
    62 {
       
    63     ASSERT(aDstColorBitmap);
       
    64     ASSERT(aSrcColorBitmap);
       
    65     ASSERT(aSrcAlphaBitmap);
       
    66     ASSERT(aDstColorBitmap->iDisplayMode == aSrcColorBitmap->iDisplayMode);
       
    67     ASSERT(BPP(aDstColorBitmap) == 16);
       
    68     ASSERT(aSrcAlphaBitmap->iDisplayMode == EGray2);
       
    69 
       
    70     TPoint srcPoint = aTransform(aDstRect.iTl);
       
    71 
       
    72     TInt dudx = aTransform.iDuDx;
       
    73     TInt dudy = aTransform.iDuDy;
       
    74     TInt dvdx = aTransform.iDvDx;
       
    75     TInt dvdy = aTransform.iDvDy;
       
    76     TInt u0   = srcPoint.iX;
       
    77     TInt v0   = srcPoint.iY;
       
    78 
       
    79     const TInt width = aDstRect.Width();
       
    80 
       
    81     const TInt srcLinePitch = aSrcColorBitmap->iLinePitch;
       
    82     const TInt mskLinePitch = aSrcAlphaBitmap->iLinePitch;
       
    83     const TInt dstLinePitch = aDstColorBitmap->iLinePitch;
       
    84 
       
    85     TUint8* srcAddress = aSrcColorBitmap->iAddress;
       
    86     TUint8* mskAddress = aSrcAlphaBitmap->iAddress; // 1 bpp
       
    87     TUint8* dstAddress = aDstColorBitmap->iAddress;
       
    88 
       
    89     TInt u;
       
    90     TInt v;
       
    91     TInt x = aDstRect.iTl.iX;
       
    92     TInt y = aDstRect.iTl.iY;
       
    93     TInt h = aDstRect.Height();
       
    94 
       
    95     //
       
    96     // Iterate over destination pixels.
       
    97     //
       
    98     dstAddress += (y*dstLinePitch + x*sizeof(TUint16));
       
    99     for (; h>0; --h)
       
   100     {
       
   101         TUint16* dst = (TUint16*)(dstAddress);
       
   102         TUint16* end = dst + width;
       
   103         u=u0;
       
   104         v=v0;
       
   105         while (dst < end)
       
   106         {
       
   107             TInt m = *(mskAddress + v*mskLinePitch + (u>>3));
       
   108             if (m & (1<<(u&0x7)))
       
   109             {
       
   110                 TUint16 srcColor = *(TUint16*)(srcAddress + v*srcLinePitch + u*sizeof(TUint16));
       
   111                 *dst = srcColor;
       
   112             }
       
   113             ++dst;
       
   114             u+=dudx;
       
   115             v+=dvdx;
       
   116         }
       
   117         u0+=dudy;
       
   118         v0+=dvdy;
       
   119         dstAddress += dstLinePitch;
       
   120     }
       
   121 }
       
   122 
       
   123 
       
   124 #ifdef LCDGD_SUPPORT_MATCHED_MASK_BITMAP
       
   125 LOCAL_C void BlitLine16Bpp16BppTo16BppOpaque
       
   126 (
       
   127     TUint8* aDstAddress,
       
   128     TInt    aWidth,
       
   129     TUint8* aColorAddress,
       
   130     TInt    aColorPixelPitch,
       
   131     TUint8* aMaskAddress,
       
   132     TInt    aMaskPixelPitch
       
   133 )
       
   134 {
       
   135     TUint16* dst = (TUint16*)(aDstAddress);
       
   136     TUint16* end = dst + aWidth;
       
   137 
       
   138     TUint8* colorAddr = aColorAddress;
       
   139     TUint8* maskAddr = aMaskAddress;
       
   140 
       
   141     while (dst < end)
       
   142     {
       
   143         TUint16 srcMask = *(TUint16*)maskAddr;
       
   144         TUint16 srcColor = *(TUint16*)colorAddr;
       
   145         TUint16 dstColor = *dst;
       
   146 
       
   147         dstColor = (srcColor & srcMask) | (dstColor & ~srcMask);
       
   148 
       
   149         *dst++ = dstColor;
       
   150 
       
   151         // Advance to next pixel in the line in each bitmap.
       
   152         colorAddr += aColorPixelPitch;
       
   153         maskAddr += aMaskPixelPitch;
       
   154     }
       
   155 }
       
   156 
       
   157 
       
   158 extern void DrawRegion16Bpp16BppTo16BppOpaque
       
   159 (
       
   160     const TAcceleratedBitmapInfo* aDstColorBitmap,
       
   161     const TAcceleratedBitmapInfo* /*aDstAlphaBitmap*/,
       
   162     const TRect&                  aDstRect,             // must be clipped to destination
       
   163     const TAcceleratedBitmapInfo* aSrcColorBitmap,
       
   164     const TAcceleratedBitmapInfo* aSrcAlphaBitmap,      // mask
       
   165     const TLcdTransform&          aTransform            // includes anchor
       
   166 )
       
   167 {
       
   168     ASSERT(aDstColorBitmap->iDisplayMode == aSrcColorBitmap->iDisplayMode);
       
   169     ASSERT(aSrcColorBitmap->iDisplayMode == aSrcAlphaBitmap->iDisplayMode);
       
   170     ASSERT(BPP(aDstColorBitmap) == 16);
       
   171 
       
   172     GenericMaskBlit(aDstColorBitmap, aDstRect, aSrcColorBitmap, aTransform,
       
   173                     aSrcAlphaBitmap, ETrue, BlitLine16Bpp16BppTo16BppOpaque);
       
   174 }
       
   175 #endif
       
   176 
       
   177 
       
   178 extern void DrawImage16Bpp1BppTo16BppOpaque
       
   179 (
       
   180     const TAcceleratedBitmapInfo* aDstColorBitmap,
       
   181     const TAcceleratedBitmapInfo* /*aDstAlphaBitmap*/,
       
   182     const TRect&                  aDstRect,             // must be clipped to destination
       
   183     const TAcceleratedBitmapInfo* aSrcColorBitmap,
       
   184     const TAcceleratedBitmapInfo* aSrcAlphaBitmap,      // mask
       
   185     const TLcdTransform&          aTransform            // includes anchor
       
   186 )
       
   187 {
       
   188     ASSERT(aDstColorBitmap->iDisplayMode == aSrcColorBitmap->iDisplayMode);
       
   189     ASSERT(aSrcAlphaBitmap->iDisplayMode == EGray2);
       
   190     ASSERT(BPP(aDstColorBitmap) == 16);
       
   191 
       
   192     ASSERT(aTransform.iDuDx == 1);
       
   193     ASSERT(aTransform.iDuDy == 0);
       
   194     ASSERT(aTransform.iDvDx == 0);
       
   195     ASSERT(aTransform.iDvDy == 1);
       
   196 
       
   197     TPoint srcPoint = aTransform(aDstRect.iTl);
       
   198 
       
   199     ASSERT(srcPoint.iX == (aDstRect.iTl.iX + aTransform.iU0));
       
   200     ASSERT(srcPoint.iY == (aDstRect.iTl.iY + aTransform.iV0));
       
   201 
       
   202     TInt u0   = srcPoint.iX;
       
   203     TInt v0   = srcPoint.iY;
       
   204     TInt u = u0;
       
   205     TInt v = v0;
       
   206     TInt mu;    // mask u coord
       
   207     TInt m = 0; // mask byte
       
   208 
       
   209     const TInt width = aDstRect.Width();
       
   210 
       
   211     const TInt srcLinePitch = aSrcColorBitmap->iLinePitch;
       
   212     const TInt mskLinePitch = aSrcAlphaBitmap->iLinePitch;
       
   213     const TInt dstLinePitch = aDstColorBitmap->iLinePitch;
       
   214 
       
   215     TUint8* srcAddress = aSrcColorBitmap->iAddress;
       
   216     TUint8* mskAddress = aSrcAlphaBitmap->iAddress; // 1 bpp
       
   217     TUint8* dstAddress = aDstColorBitmap->iAddress;
       
   218 
       
   219     TInt x = aDstRect.iTl.iX;
       
   220     TInt y = aDstRect.iTl.iY;
       
   221     TInt h = aDstRect.Height();
       
   222 
       
   223 #ifdef _DEBUG
       
   224     const TSize   srcSize  = aSrcColorBitmap->iSize;
       
   225     const TUint16* srcStart = (TUint16*)srcAddress;
       
   226     const TUint16* srcLimit = (TUint16*)(srcAddress + (srcSize.iHeight-1)*srcLinePitch + srcSize.iWidth*sizeof(TUint16));
       
   227 #endif
       
   228 
       
   229     //
       
   230     // Start address of destination pixels.
       
   231     //
       
   232     dstAddress += ((y*dstLinePitch) + (x*sizeof(TUint16)));
       
   233 
       
   234     //
       
   235     // Start address of source pixels
       
   236     //
       
   237     srcAddress += ((v*srcLinePitch) + (u*sizeof(TUint16)));
       
   238     mskAddress += ((v*mskLinePitch) + (u>>3));
       
   239 
       
   240     for (; h>0; --h)
       
   241     {
       
   242         TUint16* src = (TUint16*)srcAddress;
       
   243         TUint8*  msk = mskAddress;
       
   244         TUint16* dst = (TUint16*)dstAddress;
       
   245         TUint16* end = dst + width;
       
   246         u=u0;
       
   247         mu=-1;
       
   248         while (dst < end)
       
   249         {
       
   250 #ifdef _DEBUG
       
   251             ASSERT((srcStart <= src) && (src <= srcLimit));
       
   252 #endif
       
   253             if (mu != (u>>3))
       
   254             {
       
   255                 mu = (u>>3);
       
   256                 m  = *msk++;
       
   257             }
       
   258             if (m & (1<<(u&0x7)))
       
   259             {
       
   260                 *dst = *src;
       
   261             }
       
   262             ++src;
       
   263             ++dst;
       
   264             ++u;
       
   265         }
       
   266         dstAddress += dstLinePitch;
       
   267         srcAddress += srcLinePitch;
       
   268         mskAddress += mskLinePitch;
       
   269     }
       
   270 }
       
   271 
       
   272 LOCAL_C void FillTriangle16Bpp64
       
   273 (
       
   274     const TAcceleratedBitmapInfo* aBitmap,
       
   275     const TPoint aPoints[],
       
   276     TUint32 aColor16Bpp,
       
   277     const TRect& aClipRect
       
   278 )
       
   279 {
       
   280     TRect clipRect(aBitmap->iSize);
       
   281     clipRect.Intersection(aClipRect);
       
   282     const TInt64 clipX1 = (TInt64)(clipRect.iTl.iX);
       
   283     const TInt64 clipY1 = (TInt64)(clipRect.iTl.iY);
       
   284     const TInt64 clipX2 = (TInt64)(clipRect.iBr.iX);
       
   285     const TInt64 clipY2 = (TInt64)(clipRect.iBr.iY);
       
   286 
       
   287     TInt i;
       
   288 
       
   289     TInt ymin=0;
       
   290     TInt ymax=0;
       
   291     TInt xmin=0;
       
   292     TInt xmax=0;
       
   293 
       
   294     for (i=1; i<3; i++)
       
   295     {
       
   296         if (aPoints[i].iX < aPoints[xmin].iX) xmin = i;
       
   297         if (aPoints[i].iX > aPoints[xmax].iX) xmax = i;
       
   298         if (aPoints[i].iY < aPoints[ymin].iY) ymin = i;
       
   299         if (aPoints[i].iY > aPoints[ymax].iY) ymax = i;
       
   300     }
       
   301     const TInt ymid = 3 - (ymax + ymin);
       
   302 
       
   303 //  const TInt64 minX = aPoints[xmin].iX;
       
   304 //  const TInt64 maxX = aPoints[xmax].iX;
       
   305 
       
   306     TEdge64 edges[3];
       
   307 
       
   308     //
       
   309     // Long edge top to bottom.
       
   310     //
       
   311     edges[0].iDy = (TInt64)(aPoints[ymax].iY) - (TInt64)(aPoints[ymin].iY);
       
   312     if (edges[0].iDy == 0)
       
   313     {
       
   314         return;
       
   315     }
       
   316     edges[0].iDx = (TInt64)(aPoints[ymax].iX) - (TInt64)(aPoints[ymin].iX);
       
   317     edges[0].iX  = (TInt64)(aPoints[ymin].iX);
       
   318     edges[0].iF  = 0;
       
   319     edges[0].iD  = edges[0].iDy;
       
   320     edges[0].iDe = Sign(edges[0].iDx);
       
   321     Increment(edges[0].iIx, edges[0].iIf, edges[0].iDx, edges[0].iDy);
       
   322     ASSERT(edges[0].iDy >= 0);
       
   323 
       
   324     //
       
   325     // Short top edge, or flat top
       
   326     //
       
   327     edges[1].iDx = (TInt64)(aPoints[ymid].iX) - (TInt64)(aPoints[ymin].iX);
       
   328     edges[1].iDy = (TInt64)(aPoints[ymid].iY) - (TInt64)(aPoints[ymin].iY);
       
   329     edges[1].iX  = (TInt64)(aPoints[ymin].iX);
       
   330     edges[1].iF  = 0;
       
   331     edges[1].iD  = edges[1].iDy;
       
   332     edges[1].iDe = Sign(edges[1].iDx);
       
   333     ASSERT(edges[1].iDy >= 0);
       
   334 
       
   335     //
       
   336     // Short bottom edge or flat bottom
       
   337     //
       
   338     edges[2].iDx = (TInt64)(aPoints[ymax].iX) - (TInt64)(aPoints[ymid].iX);
       
   339     edges[2].iDy = (TInt64)(aPoints[ymax].iY) - (TInt64)(aPoints[ymid].iY);
       
   340     edges[2].iX  = (TInt64)(aPoints[ymid].iX);
       
   341     edges[2].iF  = 0;
       
   342     edges[2].iD  = edges[2].iDy;
       
   343     edges[2].iDe = Sign(edges[2].iDx);
       
   344     ASSERT(edges[2].iDy >= 0);
       
   345 
       
   346     const TBool flatTop    = (edges[1].iDy == 0);
       
   347     const TBool flatBottom = (edges[2].iDy == 0);
       
   348 
       
   349     //
       
   350     // work out whether long edge is left most or right most.
       
   351     //
       
   352     // compare slopes of long edge and top edge.
       
   353     //
       
   354     TBool longEdgeRight;
       
   355     if (flatTop)
       
   356     {
       
   357         longEdgeRight = (aPoints[ymid].iX < aPoints[ymin].iX);
       
   358     }
       
   359     else
       
   360     {
       
   361         longEdgeRight = (edges[0].iDx*edges[1].iDy) > (edges[1].iDx*edges[0].iDy);
       
   362     }
       
   363 
       
   364     TInt64   y    = (TInt64)aPoints[ymin].iY;
       
   365     TInt64   yEnd = Min(aPoints[ymid].iY, clipY2);
       
   366     TEdge64* el   = NULL;
       
   367     TEdge64* er   = NULL;
       
   368     TInt64   m;     // number of lines to skip
       
   369     TInt64   x1;    // start of clipped scan (inclusive)
       
   370     TInt64   x2;    // end of clipped scan (exclusive), exclusive overrides inclusive
       
   371 
       
   372     TInt64 eliX;    // Locals used to speed access to edge information in loops.
       
   373     TInt64 eliF;
       
   374     TInt64 eliD;
       
   375     TInt64 eriX;
       
   376     TInt64 eriF;
       
   377     TInt64 eriD;
       
   378 
       
   379     TUint8* base = aBitmap->iAddress;
       
   380     TUint8* line = NULL;
       
   381     TInt linePitch = aBitmap->iLinePitch;
       
   382     TUint16* dst;
       
   383     TUint16* end;
       
   384     TUint32 color16 = (TUint32)aColor16Bpp;
       
   385 
       
   386     //
       
   387     // render top half.
       
   388     //
       
   389     if (!flatTop)
       
   390     {
       
   391         Increment(edges[1].iIx, edges[1].iIf, edges[1].iDx, edges[1].iDy);
       
   392         if (longEdgeRight)
       
   393         {
       
   394             er = &edges[0];
       
   395             el = &edges[1];
       
   396         }
       
   397         else
       
   398         {
       
   399             er = &edges[1];
       
   400             el = &edges[0];
       
   401         }
       
   402         eliX = el->iX;
       
   403         eliF = el->iF;
       
   404         eliD = el->iD;
       
   405         eriX = er->iX;
       
   406         eriF = er->iF;
       
   407         eriD = er->iD;
       
   408 
       
   409         //
       
   410         // Clip to top of clip rect.
       
   411         //
       
   412         if (y < clipY1)
       
   413         {
       
   414             TInt64 yTop = Min(clipY1, yEnd);
       
   415 
       
   416             m = (yTop - y);
       
   417 
       
   418             double leftSlope = (double)(el->iDx)/(double)(el->iDy);
       
   419 
       
   420             eliX += (leftSlope * ((double)m));
       
   421 
       
   422             double rightSlope = (double)(er->iDx)/(double)(er->iDy);
       
   423 
       
   424             eriX += (rightSlope * ((double)m));
       
   425             y = yTop;
       
   426         }
       
   427 
       
   428         ASSERT(((1 - eriD) <= eriF) && (eriF <= 0));
       
   429         ASSERT(((1 - eliD) <= eliF) && (eliF <= 0));
       
   430 
       
   431 #ifdef PLOT_TOP_VERTEX
       
   432         // special case top vertex - can produce pimple so prob best avoided.
       
   433         if (aClipRect.Contains(aPoints[ymin]))
       
   434         {
       
   435             line = base + aPoints[ymin].iY*linePitch;
       
   436             ((TUint16*)line)[aPoints[ymin].iX] = color16;
       
   437         }
       
   438 #endif
       
   439 
       
   440         line = base + y*linePitch;
       
   441         for (; y<yEnd; y++)
       
   442         {
       
   443             ASSERT(eliX <= eriX);
       
   444             if ((eliX < clipX2) && (eriX > clipX1))
       
   445             {
       
   446                 x1 = Max(eliX, clipX1); // inclusive (ceil)
       
   447                 x2 = Min(eriX, clipX2); // exclusive (floor)
       
   448 
       
   449                 dst = (TUint16*)(line + x1*sizeof(TUint16));
       
   450                 end = (TUint16*)(line + x2*sizeof(TUint16));
       
   451                 while (dst < end)
       
   452                 {
       
   453                     *dst++ = color16;
       
   454                 }
       
   455             }
       
   456             eliX += el->iIx;
       
   457             eliF += el->iIf;
       
   458             if (eliF > 0)
       
   459             {
       
   460                 eliX ++;
       
   461                 eliF -= eliD;
       
   462             }
       
   463 
       
   464             eriX += er->iIx;
       
   465             eriF += er->iIf;
       
   466             if (eriF > 0)
       
   467             {
       
   468                 eriX ++;
       
   469                 eriF -= eriD;
       
   470             }
       
   471 
       
   472             line += linePitch;
       
   473         }
       
   474 
       
   475         el->iX = eliX;
       
   476         el->iF = eliF;
       
   477         el->iD = eliD;
       
   478         er->iX = eriX;
       
   479         er->iF = eriF;
       
   480         er->iD = eriD;
       
   481     }
       
   482 
       
   483     if (!flatBottom)
       
   484     {
       
   485         Increment(edges[2].iIx, edges[2].iIf, edges[2].iDx, edges[2].iDy);
       
   486         if (longEdgeRight)
       
   487         {
       
   488             // initialize short left edge
       
   489             er = &edges[0];
       
   490             el = &edges[2];
       
   491         }
       
   492         else
       
   493         {
       
   494             // initialize short right edge
       
   495             er = &edges[2];
       
   496             el = &edges[0];
       
   497         }
       
   498         eliX = el->iX;
       
   499         eliF = el->iF;
       
   500         eliD = el->iD;
       
   501         eriX = er->iX;
       
   502         eriF = er->iF;
       
   503         eriD = er->iD;
       
   504 
       
   505         //
       
   506         // clip to top edge of clip rect.
       
   507         //
       
   508         //
       
   509         // Clip to top of clip rect.
       
   510         //
       
   511         if (y < clipY1)
       
   512         {
       
   513             m = (clipY1 - y);
       
   514 
       
   515             double leftSlope = (double)(el->iDx)/(double)(el->iDy);
       
   516 
       
   517             eliX += (leftSlope * m);
       
   518 
       
   519             double rightSlope = (double)(er->iDx)/(double)(er->iDy);
       
   520 
       
   521             eriX += (rightSlope * m);
       
   522 
       
   523             y = clipY1;
       
   524         }
       
   525 
       
   526         line = base + y*linePitch;
       
   527         yEnd = Min(aPoints[ymax].iY, clipY2);
       
   528         for (; y<yEnd; y++)     // ignore last line - as pixel will be on bottom edge.
       
   529         {
       
   530             ASSERT(eliX <= eriX);
       
   531             if ((eliX < clipX2) && (eriX > clipX1))
       
   532             {
       
   533                 x1 = Max(eliX, clipX1); // inclusive (ceil)
       
   534                 x2 = Min(eriX, clipX2); // exclusive (floor)
       
   535 
       
   536                 dst = (TUint16*)(line + x1*sizeof(TUint16));
       
   537                 end = (TUint16*)(line + x2*sizeof(TUint16));
       
   538                 while (dst < end)
       
   539                 {
       
   540                     *dst++ = color16;
       
   541                 }
       
   542             }
       
   543 
       
   544             eliX += el->iIx;
       
   545             eliF += el->iIf;
       
   546             if (eliF > 0)
       
   547             {
       
   548                 eliX ++;
       
   549                 eliF -= eliD;
       
   550             }
       
   551 
       
   552             eriX += er->iIx;
       
   553             eriF += er->iIf;
       
   554             if (eriF > 0)
       
   555             {
       
   556                 eriX ++;
       
   557                 eriF -= eriD;
       
   558             }
       
   559 
       
   560             line += linePitch;
       
   561         }
       
   562 
       
   563         el->iX = eliX;
       
   564         el->iF = eliF;
       
   565         el->iD = eliD;
       
   566         er->iX = eriX;
       
   567         er->iF = eriF;
       
   568         er->iD = eriD;
       
   569     }
       
   570 }
       
   571 
       
   572 extern void FillTriangle16Bpp32
       
   573 (
       
   574     const TAcceleratedBitmapInfo* aBitmap,
       
   575     const TPoint aPoints[],
       
   576     TUint32 aColor16Bpp,
       
   577     const TRect& aClipRect
       
   578 )
       
   579 {
       
   580     TRect clipRect(aBitmap->iSize);
       
   581     clipRect.Intersection(aClipRect);
       
   582     const TInt clipX1 = clipRect.iTl.iX;
       
   583     const TInt clipY1 = clipRect.iTl.iY;
       
   584     const TInt clipX2 = clipRect.iBr.iX;
       
   585     const TInt clipY2 = clipRect.iBr.iY;
       
   586 
       
   587     TInt i;
       
   588 
       
   589     TInt ymin=0;
       
   590     TInt ymax=0;
       
   591     TInt xmin=0;
       
   592     TInt xmax=0;
       
   593 
       
   594     for (i=1; i<3; i++)
       
   595     {
       
   596         if (aPoints[i].iX < aPoints[xmin].iX) xmin = i;
       
   597         if (aPoints[i].iX > aPoints[xmax].iX) xmax = i;
       
   598         if (aPoints[i].iY < aPoints[ymin].iY) ymin = i;
       
   599         if (aPoints[i].iY > aPoints[ymax].iY) ymax = i;
       
   600     }
       
   601     const TInt ymid = 3 - (ymax + ymin);
       
   602 
       
   603 
       
   604     TEdge edges[3];
       
   605 
       
   606     //
       
   607     // Long edge top to bottom.
       
   608     //
       
   609     edges[0].iDy = aPoints[ymax].iY - aPoints[ymin].iY;
       
   610     if (edges[0].iDy == 0)
       
   611     {
       
   612         return;
       
   613     }
       
   614     edges[0].iDx = aPoints[ymax].iX - aPoints[ymin].iX;
       
   615     edges[0].iX  = aPoints[ymin].iX;
       
   616     edges[0].iF  = 0;
       
   617     edges[0].iD  = edges[0].iDy;
       
   618     edges[0].iDe = Sign(edges[0].iDx);
       
   619     Increment(edges[0].iIx, edges[0].iIf, edges[0].iDx, edges[0].iDy);
       
   620     ASSERT(edges[0].iDy >= 0);
       
   621 
       
   622     //
       
   623     // Short top edge, or flat top
       
   624     //
       
   625     edges[1].iDx = aPoints[ymid].iX - aPoints[ymin].iX;
       
   626     edges[1].iDy = aPoints[ymid].iY - aPoints[ymin].iY;
       
   627     edges[1].iX  = aPoints[ymin].iX;
       
   628     edges[1].iF  = 0;
       
   629     edges[1].iD  = edges[1].iDy;
       
   630     edges[1].iDe = Sign(edges[1].iDx);
       
   631     ASSERT(edges[1].iDy >= 0);
       
   632 
       
   633     //
       
   634     // Short bottom edge or flat bottom
       
   635     //
       
   636     edges[2].iDx = aPoints[ymax].iX - aPoints[ymid].iX;
       
   637     edges[2].iDy = aPoints[ymax].iY - aPoints[ymid].iY;
       
   638     edges[2].iX  = aPoints[ymid].iX;
       
   639     edges[2].iF  = 0;
       
   640     edges[2].iD  = edges[2].iDy;
       
   641     edges[2].iDe = Sign(edges[2].iDx);
       
   642     ASSERT(edges[2].iDy >= 0);
       
   643 
       
   644     const TBool flatTop    = (edges[1].iDy == 0);
       
   645     const TBool flatBottom = (edges[2].iDy == 0);
       
   646 
       
   647     //
       
   648     // work out whether long edge is left most or right most.
       
   649     //
       
   650     // compare slopes of long edge and top edge.
       
   651     //
       
   652     TBool longEdgeRight;
       
   653     if (flatTop)
       
   654     {
       
   655         longEdgeRight = (aPoints[ymid].iX < aPoints[ymin].iX);
       
   656     }
       
   657     else
       
   658     {
       
   659         longEdgeRight = (edges[0].iDx*edges[1].iDy) > (edges[1].iDx*edges[0].iDy);
       
   660     }
       
   661 
       
   662     TInt y    = aPoints[ymin].iY;
       
   663     TInt yEnd = Min(aPoints[ymid].iY, clipY2);
       
   664     TEdge* el = NULL;
       
   665     TEdge* er = NULL;
       
   666     TInt m;     // number of lines to skip
       
   667     TInt x1;    // start of clipped scan (inclusive)
       
   668     TInt x2;    // end of clipped scan (exclusive), exclusive overrides inclusive
       
   669 
       
   670     TInt eliX;  // Locals used to speed access to edge information in loops.
       
   671     TInt eliF;
       
   672     TInt eliD;
       
   673     TInt eriX;
       
   674     TInt eriF;
       
   675     TInt eriD;
       
   676 
       
   677 
       
   678     TUint8* base = aBitmap->iAddress;
       
   679     TUint8* line = NULL;
       
   680     TInt linePitch = aBitmap->iLinePitch;
       
   681     TUint16* dst;
       
   682     TUint16* end;
       
   683     TUint16 color16 = (TUint16)aColor16Bpp;
       
   684 
       
   685     //
       
   686     // render top half.
       
   687     //
       
   688     if (!flatTop)
       
   689     {
       
   690         Increment(edges[1].iIx, edges[1].iIf, edges[1].iDx, edges[1].iDy);
       
   691         if (longEdgeRight)
       
   692         {
       
   693             er = &edges[0];
       
   694             el = &edges[1];
       
   695         }
       
   696         else
       
   697         {
       
   698             er = &edges[1];
       
   699             el = &edges[0];
       
   700         }
       
   701         eliX = el->iX;
       
   702         eliF = el->iF;
       
   703         eliD = el->iD;
       
   704         eriX = er->iX;
       
   705         eriF = er->iF;
       
   706         eriD = er->iD;
       
   707 
       
   708         //
       
   709         // Clip to top of clip rect.
       
   710         //
       
   711         if (y < clipY1)
       
   712         {
       
   713             TInt yTop = Min(clipY1, yEnd);
       
   714 
       
   715             m = (yTop - y);
       
   716 
       
   717             eliX += m*el->iIx;
       
   718             eliF += m*el->iIf;
       
   719             while (eliF > 0)
       
   720             {
       
   721                 eliX ++;
       
   722                 eliF -= eliD;
       
   723             }
       
   724 
       
   725             eriX += m*er->iIx;
       
   726             eriF += m*er->iIf;
       
   727             while (eriF > 0)
       
   728             {
       
   729                 eriX ++;
       
   730                 eriF -= eriD;
       
   731             }
       
   732 
       
   733             y = yTop;
       
   734         }
       
   735 
       
   736         ASSERT(((1 - eriD) <= eriF) && (eriF <= 0));
       
   737         ASSERT(((1 - eliD) <= eliF) && (eliF <= 0));
       
   738 
       
   739 #ifdef PLOT_TOP_VERTEX
       
   740         // special case top vertex - can produce pimple so prob best avoided.
       
   741         if (aClipRect.Contains(aPoints[ymin]))
       
   742         {
       
   743             line = base + aPoints[ymin].iY*linePitch;
       
   744             ((TUint16*)line)[aPoints[ymin].iX] = color16;
       
   745         }
       
   746 #endif
       
   747 
       
   748         line = base + y*linePitch;
       
   749         for (; y<yEnd; y++)
       
   750         {
       
   751             ASSERT(eliX <= eriX);
       
   752             if ((eliX < clipX2) && (eriX > clipX1))
       
   753             {
       
   754                 x1 = Max(eliX, clipX1); // inclusive (ceil)
       
   755                 x2 = Min(eriX, clipX2); // exclusive (floor)
       
   756 
       
   757                 dst = (TUint16*)(line + x1*sizeof(TUint16));
       
   758                 end = (TUint16*)(line + x2*sizeof(TUint16));
       
   759                 while (dst < end)
       
   760                 {
       
   761                     *dst++ = color16;
       
   762                 }
       
   763             }
       
   764 
       
   765             eliX += el->iIx;
       
   766             eliF += el->iIf;
       
   767             if (eliF > 0)
       
   768             {
       
   769                 eliX ++;
       
   770                 eliF -= eliD;
       
   771             }
       
   772 
       
   773             eriX += er->iIx;
       
   774             eriF += er->iIf;
       
   775             if (eriF > 0)
       
   776             {
       
   777                 eriX ++;
       
   778                 eriF -= eriD;
       
   779             }
       
   780 
       
   781             line += linePitch;
       
   782         }
       
   783 
       
   784         el->iX = eliX;
       
   785         el->iF = eliF;
       
   786         el->iD = eliD;
       
   787         er->iX = eriX;
       
   788         er->iF = eriF;
       
   789         er->iD = eriD;
       
   790     }
       
   791 
       
   792     if (!flatBottom)
       
   793     {
       
   794         Increment(edges[2].iIx, edges[2].iIf, edges[2].iDx, edges[2].iDy);
       
   795         if (longEdgeRight)
       
   796         {
       
   797             // initialize short left edge
       
   798             er = &edges[0];
       
   799             el = &edges[2];
       
   800         }
       
   801         else
       
   802         {
       
   803             // initialize short right edge
       
   804             er = &edges[2];
       
   805             el = &edges[0];
       
   806         }
       
   807         eliX = el->iX;
       
   808         eliF = el->iF;
       
   809         eliD = el->iD;
       
   810         eriX = er->iX;
       
   811         eriF = er->iF;
       
   812         eriD = er->iD;
       
   813 
       
   814         //
       
   815         // clip to top edge of clip rect.
       
   816         //
       
   817         //
       
   818         // Clip to top of clip rect.
       
   819         //
       
   820         if (y < clipY1)
       
   821         {
       
   822             m = (clipY1 - y);
       
   823 
       
   824             eliX += m*el->iIx;
       
   825             eliF += m*el->iIf;
       
   826             while (eliF > 0)
       
   827             {
       
   828                 eliX ++;
       
   829                 eliF -= eliD;
       
   830             }
       
   831 
       
   832             eriX += m*er->iIx;
       
   833             eriF += m*er->iIf;
       
   834             while (eriF > 0)
       
   835             {
       
   836                 eriX ++;
       
   837                 eriF -= eriD;
       
   838             }
       
   839             y = clipY1;
       
   840         }
       
   841 
       
   842         line = base + y*linePitch;
       
   843         yEnd = Min(aPoints[ymax].iY, clipY2);
       
   844         for (; y<yEnd; y++)     // ignore last line - as pixel will be on bottom edge.
       
   845         {
       
   846             ASSERT(eliX <= eriX);
       
   847             if ((eliX < clipX2) && (eriX > clipX1))
       
   848             {
       
   849                 x1 = Max(eliX, clipX1); // inclusive (ceil)
       
   850                 x2 = Min(eriX, clipX2); // exclusive (floor)
       
   851 
       
   852                 dst = (TUint16*)(line + x1*sizeof(TUint16));
       
   853                 end = (TUint16*)(line + x2*sizeof(TUint16));
       
   854                 while (dst < end)
       
   855                 {
       
   856                     *dst++ = color16;
       
   857                 }
       
   858             }
       
   859 
       
   860             eliX += el->iIx;
       
   861             eliF += el->iIf;
       
   862             if (eliF > 0)
       
   863             {
       
   864                 eliX ++;
       
   865                 eliF -= eliD;
       
   866             }
       
   867 
       
   868             eriX += er->iIx;
       
   869             eriF += er->iIf;
       
   870             if (eriF > 0)
       
   871             {
       
   872                 eriX ++;
       
   873                 eriF -= eriD;
       
   874             }
       
   875 
       
   876             line += linePitch;
       
   877         }
       
   878 
       
   879         el->iX = eliX;
       
   880         el->iF = eliF;
       
   881         el->iD = eliD;
       
   882         er->iX = eriX;
       
   883         er->iF = eriF;
       
   884         er->iD = eriD;
       
   885     }
       
   886 }
       
   887 
       
   888 LOCAL_C TBool IsPathologicalTriangle(const TPoint aPoints[3])
       
   889 {
       
   890     TInt minX = aPoints[0].iX;
       
   891     TInt maxX = aPoints[0].iX;
       
   892     TInt minY = aPoints[0].iY;
       
   893     TInt maxY = aPoints[0].iY;
       
   894 
       
   895     for (TInt i = 1; i <= 2; i++)
       
   896     {
       
   897         TInt x = aPoints[i].iX;
       
   898         TInt y = aPoints[i].iY;
       
   899 
       
   900         if (x < minX)
       
   901         {
       
   902             minX = x;
       
   903         }
       
   904         if (x > maxX)
       
   905         {
       
   906             maxX = x;
       
   907         }
       
   908         if (y < minY)
       
   909         {
       
   910             minY = y;
       
   911         }
       
   912         if (y > maxY)
       
   913         {
       
   914             maxY = y;
       
   915         }
       
   916     }
       
   917     if (minX < 0)
       
   918     {
       
   919         if (maxX >= (0x7FFFFFFF + minX))
       
   920         {
       
   921             return ETrue;
       
   922         }
       
   923         if (-minX > 0xFFFFF)
       
   924         {
       
   925             return ETrue;
       
   926         }
       
   927     }
       
   928     if (maxX > 0)
       
   929     {
       
   930         if ((maxX == 0x7FFFFFFF) && (minX == 0))
       
   931         {
       
   932             return ETrue;
       
   933         }
       
   934         if (maxX > 0xFFFFF)
       
   935         {
       
   936             return ETrue;
       
   937         }
       
   938     }
       
   939     if (minY < 0)
       
   940     {
       
   941         if (maxY >= (0x7FFFFFFF + minY))
       
   942         {
       
   943             return ETrue;
       
   944         }
       
   945         if (-minY > 0xFFFFF)
       
   946         {
       
   947             return ETrue;
       
   948         }
       
   949     }
       
   950     if (maxY > 0)
       
   951     {
       
   952         if ((maxY == 0x7FFFFFFF) && (minY == 0))
       
   953         {
       
   954             return ETrue;
       
   955         }
       
   956         if (maxY > 0xFFFFF)
       
   957         {
       
   958             return ETrue;
       
   959         }
       
   960     }
       
   961     return EFalse;
       
   962 }
       
   963 
       
   964 extern void FillTriangle16Bpp
       
   965 (
       
   966     const TAcceleratedBitmapInfo* aBitmap,
       
   967     const TPoint aPoints[],
       
   968     TUint32 aColor16Bpp,
       
   969     const TRect& aClipRect
       
   970 )
       
   971 {
       
   972     if (!IsPathologicalTriangle(aPoints))
       
   973     {
       
   974         FillTriangle16Bpp32(aBitmap, aPoints, aColor16Bpp, aClipRect);
       
   975     }
       
   976     else
       
   977     {
       
   978         FillTriangle16Bpp64(aBitmap, aPoints, aColor16Bpp, aClipRect);
       
   979     }
       
   980 }
       
   981 
       
   982 LOCAL_C void BlitLineSixteenBppSimple
       
   983 (
       
   984     TUint8* aDstAddress,
       
   985     TInt    aWidth,
       
   986     TUint8* aColorAddress,
       
   987     TInt    DEBUG_ONLY(aColorPixelPitch)
       
   988 )
       
   989 {
       
   990     ASSERT(aColorPixelPitch == sizeof(TUint16));
       
   991 #ifdef USE_MEM_COPY_FOR_SIMPLE_BLIT
       
   992     Mem::Copy(aDstAddress, aColorAddress, aWidth * sizeof(TUint16));
       
   993 #else
       
   994     TUint16* dst = (TUint16*)aDstAddress;
       
   995     TUint16* src = (TUint16*)aColorAddress;
       
   996     TUint16* end = dst + aWidth;
       
   997     while (dst < end)
       
   998     {
       
   999         *dst++ = *src++;
       
  1000     }
       
  1001 #endif
       
  1002 }
       
  1003 
       
  1004 
       
  1005 /**
       
  1006  * Opaque 16bpp to 16bpp bitblt with simple transform.
       
  1007  */
       
  1008 extern void BitBltSixteenBppSimple
       
  1009 (
       
  1010     const TAcceleratedBitmapInfo*   aDstColorBitmap,
       
  1011     const TAcceleratedBitmapInfo*   /*aDstAlphaBitmap*/,
       
  1012     const TRect&                    aDstRect,
       
  1013     const TAcceleratedBitmapInfo*   aSrcColorBitmap,
       
  1014     const TAcceleratedBitmapInfo*   /*aSrcAlphaBitmap*/,
       
  1015     const TLcdTransform&            aTransform
       
  1016 )
       
  1017 {
       
  1018     //
       
  1019     // Translation or translation & vertical reflection case.
       
  1020     //
       
  1021     ASSERT(aTransform.iDuDx == 1);
       
  1022     ASSERT(aTransform.iDuDy == 0);
       
  1023     ASSERT(aTransform.iDvDx == 0);
       
  1024     ASSERT(aTransform.iDvDy == 1 || aTransform.iDvDy == -1);
       
  1025 
       
  1026     GenericBlit(aDstColorBitmap, aDstRect, aSrcColorBitmap, aTransform,
       
  1027                 BlitLineSixteenBppSimple);
       
  1028 }
       
  1029 
       
  1030 
       
  1031 LOCAL_C void BlitLineSixteenBpp
       
  1032 (
       
  1033     TUint8* aDstAddress,
       
  1034     TInt    aWidth,
       
  1035     TUint8* aColorAddress,
       
  1036     TInt    aColorPixelPitch
       
  1037 )
       
  1038 {
       
  1039     TUint16* dst = (TUint16*)aDstAddress;
       
  1040     TUint16* end = dst + aWidth;
       
  1041 
       
  1042     TUint8* colorAddr = aColorAddress;
       
  1043     while (dst < end)
       
  1044     {
       
  1045         *dst++ = *(TUint16*)colorAddr;
       
  1046         colorAddr += aColorPixelPitch;
       
  1047     }
       
  1048 }
       
  1049 
       
  1050 
       
  1051 /**
       
  1052  * Opaque 16bpp to 16bpp bitblt with transform.
       
  1053  */
       
  1054 extern void BitBltSixteenBpp
       
  1055 (
       
  1056     const TAcceleratedBitmapInfo*   aDstColorBitmap,
       
  1057     const TAcceleratedBitmapInfo*   /*aDstAlphaBitmap*/,
       
  1058     const TRect&                    aDstRect,
       
  1059     const TAcceleratedBitmapInfo*   aSrcColorBitmap,
       
  1060     const TAcceleratedBitmapInfo*   /*aSrcAlphaBitmap*/,
       
  1061     const TLcdTransform&            aTransform
       
  1062 )
       
  1063 {
       
  1064     GenericBlit(aDstColorBitmap, aDstRect, aSrcColorBitmap, aTransform,
       
  1065                 BlitLineSixteenBpp);
       
  1066 }
       
  1067 
       
  1068 extern void BitBltSixteenBppOneBpp
       
  1069 (
       
  1070     const TAcceleratedBitmapInfo*   aDstColorBitmap,
       
  1071     const TAcceleratedBitmapInfo*   aDstAlphaBitmap,
       
  1072     const TRect&                    aDstRect,
       
  1073     const TAcceleratedBitmapInfo*   aSrcColorBitmap,
       
  1074     const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
       
  1075     const TLcdTransform&            aTransform
       
  1076 )
       
  1077 {
       
  1078     BitBltSixteenBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform);
       
  1079     BitBltOneBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform);
       
  1080 }
       
  1081 
       
  1082 extern void BitBltSixteenBppSixteenBpp
       
  1083 (
       
  1084     const TAcceleratedBitmapInfo*   aDstColorBitmap,
       
  1085     const TAcceleratedBitmapInfo*   aDstAlphaBitmap,
       
  1086     const TRect&                    aDstRect,
       
  1087     const TAcceleratedBitmapInfo*   aSrcColorBitmap,
       
  1088     const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
       
  1089     const TLcdTransform&            aTransform
       
  1090 )
       
  1091 {
       
  1092     BitBltSixteenBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform);
       
  1093     BitBltSixteenBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform);
       
  1094 }
       
  1095 
       
  1096 extern void BitBltSixteenBppEightBpp
       
  1097 (
       
  1098     const TAcceleratedBitmapInfo*   aDstColorBitmap,
       
  1099     const TAcceleratedBitmapInfo*   aDstAlphaBitmap,
       
  1100     const TRect&                    aDstRect,
       
  1101     const TAcceleratedBitmapInfo*   aSrcColorBitmap,
       
  1102     const TAcceleratedBitmapInfo*   aSrcAlphaBitmap,
       
  1103     const TLcdTransform&            aTransform
       
  1104 )
       
  1105 {
       
  1106     BitBltSixteenBpp(aDstColorBitmap, NULL, aDstRect, aSrcColorBitmap, NULL, aTransform);
       
  1107     BitBltEightBpp(aDstAlphaBitmap, NULL, aDstRect, aSrcAlphaBitmap, NULL, aTransform);
       
  1108 }
       
  1109