uiacceltk/hitchcock/coretoolkit/src/HuiUtil.cpp
changeset 0 15bf7259bb7c
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006-2007 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:   Implementation for HuiUtil class, a collection of utility 
       
    15 *                routines for HUITK.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include "uiacceltk/HuiUtil.h"
       
    22 #include "uiacceltk/HuiFont.h"
       
    23 #include "uiacceltk/HuiRealPoint.h"
       
    24 
       
    25 #include <e32math.h>
       
    26 #include <hal.h>
       
    27 #include <AknUtils.h>
       
    28 #include <AknFontSpecification.h> 
       
    29 #include <AknFontAccess.h> 
       
    30 #include <centralrepository.h>
       
    31 #include "uiacceltk/HuiDisplay.h"
       
    32 #include "../../CommonInc/uiacceltkdomaincrkeys.h"
       
    33 
       
    34 const TReal32 KLengthUnitDivisor = 320.0;
       
    35 
       
    36 /// Character used for separating tags in a tag descriptor.
       
    37 const TInt KTagSeparator = ':';
       
    38 
       
    39 
       
    40 // Calculates the smallest power-of-two that is equal to or greater than
       
    41 // a value.
       
    42 EXPORT_C TInt HuiUtil::Power2(TInt aValue)
       
    43     {
       
    44     ASSERT(aValue>0);
       
    45     if(aValue<=0)
       
    46         {
       
    47         return 0;
       
    48         }
       
    49 
       
    50     TInt i;
       
    51     for(i = 1; i < aValue && i < KMaxTInt/2; i *= 2)
       
    52         {}
       
    53     return i;
       
    54     }
       
    55 
       
    56 EXPORT_C TInt HuiUtil::Power2RoundDown(TInt aValue)
       
    57     {
       
    58     ASSERT(aValue>0);
       
    59     if(aValue <= 0)
       
    60         {
       
    61         return 0;
       
    62         }
       
    63 
       
    64     TInt i = 1;
       
    65     for(; (i * 4 <= aValue) && (i < KMaxTInt/4); i *= 4)
       
    66         {}
       
    67     for(; (i * 2 <= aValue) && (i < KMaxTInt/2); i *= 2)
       
    68         {}
       
    69     return i;
       
    70     }
       
    71 
       
    72 
       
    73 EXPORT_C TReal32 HuiUtil::Interpolate(TReal32 aPos, TReal32 aMin, TReal32 aMax) __SOFTFP
       
    74     {
       
    75     aPos = Max(0.f, aPos);
       
    76     aPos = Min(aPos, 1.f);
       
    77     return (1.f - aPos) * aMin + aPos * aMax;
       
    78     }
       
    79 
       
    80 
       
    81 EXPORT_C void HuiUtil::WrapValue(TReal32& aValue, TReal32 aLow, TReal32 aHigh) __SOFTFP 
       
    82     {
       
    83     TReal32 segments = 0;
       
    84     TReal32 length = aHigh - aLow;
       
    85 
       
    86     if(length <= 0)
       
    87         {
       
    88         aValue = aLow;
       
    89         return;
       
    90         }
       
    91     
       
    92     // check rounding errors for low limit    
       
    93     if ( HuiUtil::RealCompare( aValue, aLow ) )
       
    94         {
       
    95         aValue = aLow;
       
    96         return;
       
    97         }
       
    98        
       
    99     // check rounding errors for high limit  
       
   100     if ( HuiUtil::RealCompare( aValue, aHigh ) )
       
   101         {
       
   102         aValue = aHigh;
       
   103         return;
       
   104         }
       
   105 
       
   106     if(aValue < aLow)
       
   107         {
       
   108         // Wrap from below.
       
   109         segments = (aLow - aValue) / length;
       
   110         aValue += (TInt(segments) + 1) * length;
       
   111         }
       
   112     else if(aValue >= aHigh)
       
   113         {
       
   114         // Wrap from above.
       
   115         segments = (aValue - aHigh) / length;
       
   116         aValue -= (TInt(segments) + 1) * length;
       
   117         }
       
   118     else
       
   119         {
       
   120         // for PC lint
       
   121         }
       
   122     }
       
   123 
       
   124 
       
   125 EXPORT_C TInt HuiUtil::RandomInt(TInt aMin, TInt aMax)
       
   126     {
       
   127     TUint32 random = Math::Random();
       
   128     TUint range = aMax - aMin;
       
   129     if(range > 0)
       
   130         {
       
   131         return aMin + (random % (range + 1));
       
   132         }
       
   133     else
       
   134         {
       
   135         return aMin;
       
   136         }
       
   137     }
       
   138 
       
   139 
       
   140 EXPORT_C TReal32 HuiUtil::RandomReal(TReal32 aMin, TReal32 aMax) __SOFTFP 
       
   141     {
       
   142     /** @todo  Could use Math::FRand(). */
       
   143     TReal32 random = RandomInt(0, 10000000) / 10000000.f;
       
   144     return aMin + (aMax - aMin) * random;
       
   145     }
       
   146 
       
   147 
       
   148 EXPORT_C TUint HuiUtil::FreeMemory(TUint* aTotalMemory)
       
   149     {
       
   150     TInt total = 0;
       
   151     TInt free = 0;
       
   152 
       
   153     HAL::Get(HALData::EMemoryRAM, total);
       
   154     HAL::Get(HALData::EMemoryRAMFree, free);
       
   155     if(aTotalMemory)
       
   156         {
       
   157         *aTotalMemory = total;
       
   158         }
       
   159     return free;
       
   160     }
       
   161 
       
   162 
       
   163 EXPORT_C TSize HuiUtil::ScreenSize()
       
   164     {
       
   165     TSize screenSize(320, 240);
       
   166 
       
   167     if ( CCoeEnv::Static())
       
   168         {
       
   169         AknLayoutUtils::LayoutMetricsSize(AknLayoutUtils::EScreen, screenSize);
       
   170         }
       
   171     else
       
   172         {
       
   173         screenSize = CHuiStatic::ScreenDevice()->SizeInPixels();
       
   174         }
       
   175     
       
   176     return screenSize;
       
   177     }
       
   178 
       
   179 
       
   180 EXPORT_C TReal32 HuiUtil::LengthUnit() __SOFTFP
       
   181     {
       
   182     return Max(ScreenSize().iWidth, ScreenSize().iHeight) / KLengthUnitDivisor;
       
   183     }
       
   184 
       
   185 
       
   186 EXPORT_C TReal32 HuiUtil::QuickLength(THuiRealPoint& aVector) __SOFTFP
       
   187     {
       
   188     TReal32 dx = Abs(aVector.iX);
       
   189     TReal32 dy = Abs(aVector.iY);
       
   190     if(dx < dy)
       
   191         {
       
   192         return dx + dy - dx/2;
       
   193         }
       
   194     else
       
   195         {
       
   196         return dx + dy - dy/2;
       
   197         }
       
   198     }
       
   199 
       
   200 
       
   201 EXPORT_C TReal32 HuiUtil::QuickLength(TReal32 aDx, TReal32 aDy) __SOFTFP
       
   202     {
       
   203     TReal32 dx = Abs(aDx);
       
   204     TReal32 dy = Abs(aDy);
       
   205     if(dx < dy)
       
   206         {
       
   207         return dx + dy - dx/2;
       
   208         }
       
   209     else
       
   210         {
       
   211         return dx + dy - dy/2;
       
   212         }
       
   213     }
       
   214 
       
   215 
       
   216 EXPORT_C void HuiUtil::QuickNormalize(THuiRealPoint& aNormal)
       
   217     {
       
   218     TReal32 approxLength = QuickLength(aNormal);
       
   219 
       
   220     if(approxLength > 0)
       
   221         {
       
   222         aNormal.iX /= approxLength;
       
   223         aNormal.iY /= approxLength;
       
   224         }
       
   225     }
       
   226 
       
   227 
       
   228 EXPORT_C void HuiUtil::QuickNormalize(TReal32 aVector[3])
       
   229     {
       
   230     TReal32 approxLength = QuickLength(QuickLength(aVector[0], aVector[1]), aVector[2]);
       
   231 
       
   232     if(approxLength > 0)
       
   233         {
       
   234         aVector[0] /= approxLength;
       
   235         aVector[1] /= approxLength;
       
   236         aVector[2] /= approxLength;
       
   237         }
       
   238     }
       
   239 
       
   240 
       
   241 EXPORT_C void HuiUtil::CrossProduct(const TReal32 aA[3], const TReal32 aB[3],
       
   242                                     TReal32 aProduct[3])
       
   243     {
       
   244     aProduct[0] = aA[1] * aB[2] - aB[1] * aA[2];
       
   245     aProduct[1] = aA[2] * aB[0] - aB[2] * aA[0];
       
   246     aProduct[2] = aA[0] * aB[1] - aB[0] * aA[1];
       
   247     }
       
   248 
       
   249 
       
   250 EXPORT_C void HuiUtil::NormalFromPoints(const TReal32 aPoints[3][3], TReal32 aNormal[3])
       
   251     {
       
   252     TReal32 vectors[2][3];
       
   253     TInt i;
       
   254 
       
   255     for(i = 0; i < 3; ++i)
       
   256         {
       
   257         vectors[0][i] = aPoints[0][i] - aPoints[1][i];
       
   258         vectors[1][i] = aPoints[0][i] - aPoints[2][i];
       
   259         }
       
   260 
       
   261     CrossProduct(vectors[0], vectors[1], aNormal);
       
   262     QuickNormalize(aNormal);
       
   263     }
       
   264 
       
   265 
       
   266 EXPORT_C void HuiUtil::ShadowMatrix(const TReal32 aPlanePoint[3],
       
   267                                     const TReal32 aPlaneNormal[3],
       
   268                                     const TReal32 aLightPos[4],
       
   269                                     TReal32 aDestMat[16])
       
   270     {
       
   271     TReal32 planeCoeff[4];
       
   272     TReal32 dot;
       
   273 
       
   274     // Find the plane equation coefficients
       
   275     // Find the first three coefficients the same way we find a normal.
       
   276     //NormalFromPoints(aPoints, planeCoeff);
       
   277 
       
   278     planeCoeff[0] = aPlaneNormal[0];
       
   279     planeCoeff[1] = aPlaneNormal[1];
       
   280     planeCoeff[2] = aPlaneNormal[2];
       
   281 
       
   282     // Find the last coefficient by back substitutions
       
   283     planeCoeff[3] = - ((planeCoeff[0] * aPlanePoint[0]) + (planeCoeff[1] * aPlanePoint[1]) +
       
   284                        (planeCoeff[2] * aPlanePoint[2]));
       
   285 
       
   286     // Dot product of plane and light position
       
   287     dot = planeCoeff[0] * aLightPos[0] + planeCoeff[1] * aLightPos[1] +
       
   288           planeCoeff[2] * aLightPos[2] + planeCoeff[3] * aLightPos[3];
       
   289 
       
   290     // Now do the projection
       
   291     // First column
       
   292     aDestMat[0] = dot - aLightPos[0] * planeCoeff[0];
       
   293     aDestMat[4] = 0.0f - aLightPos[0] * planeCoeff[1];
       
   294     aDestMat[8] = 0.0f - aLightPos[0] * planeCoeff[2];
       
   295     aDestMat[12] = 0.0f - aLightPos[0] * planeCoeff[3];
       
   296 
       
   297     // Second column
       
   298     aDestMat[1] = 0.0f - aLightPos[1] * planeCoeff[0];
       
   299     aDestMat[5] = dot - aLightPos[1] * planeCoeff[1];
       
   300     aDestMat[9] = 0.0f - aLightPos[1] * planeCoeff[2];
       
   301     aDestMat[13] = 0.0f - aLightPos[1] * planeCoeff[3];
       
   302 
       
   303     // Third Column
       
   304     aDestMat[2] = 0.0f - aLightPos[2] * planeCoeff[0];
       
   305     aDestMat[6] = 0.0f - aLightPos[2] * planeCoeff[1];
       
   306     aDestMat[10] = dot - aLightPos[2] * planeCoeff[2];
       
   307     aDestMat[14] = 0.0f - aLightPos[2] * planeCoeff[3];
       
   308 
       
   309     // Fourth Column
       
   310     aDestMat[3] = 0.0f - aLightPos[3] * planeCoeff[0];
       
   311     aDestMat[7] = 0.0f - aLightPos[3] * planeCoeff[1];
       
   312     aDestMat[11] = 0.0f - aLightPos[3] * planeCoeff[2];
       
   313     aDestMat[15] = dot - aLightPos[3] * planeCoeff[3];
       
   314     }
       
   315 
       
   316 
       
   317 EXPORT_C TReal32 HuiUtil::ColorLightness(const TRgb& aColor) __SOFTFP
       
   318     {
       
   319     TReal32 red = aColor.Red() / 255.0f;
       
   320     TReal32 green = aColor.Red() / 255.0f;
       
   321     TReal32 blue = aColor.Red() / 255.0f;
       
   322 
       
   323     return (red*2 + green*3 + blue) / 6.f;
       
   324     }
       
   325 
       
   326 EXPORT_C void HuiUtil::ScaleFbsBitmapL(const CFbsBitmap & aSrcBitmap,
       
   327                                        CFbsBitmap & aScaledBitmap)
       
   328     {
       
   329     CFbsDevice* targetdevice = NULL;
       
   330     CFbsBitGc* gc = NULL;
       
   331     // create device for drawing onto the target cropped bitmap area
       
   332     targetdevice = CFbsBitmapDevice::NewL(&aScaledBitmap);
       
   333     CleanupStack::PushL(targetdevice);
       
   334     // create graphics context for drawing
       
   335     User::LeaveIfError(targetdevice->CreateContext(gc));
       
   336     // Perform downscale using DrawBitmap
       
   337     gc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);    
       
   338     gc->DrawBitmap(TRect(TPoint(0,0), aScaledBitmap.SizeInPixels()),
       
   339                    (const CFbsBitmap *)&aSrcBitmap);
       
   340     delete gc;
       
   341     CleanupStack::PopAndDestroy(targetdevice);
       
   342     }
       
   343 
       
   344 EXPORT_C void HuiUtil::CombineMaskFbsBitmapL(const CFbsBitmap & aSrcBitmap,
       
   345                                              const CFbsBitmap & aSrcMaskBitmap,
       
   346                                              CFbsBitmap & aCombinedBitmap)
       
   347     {
       
   348 
       
   349     ASSERT(aCombinedBitmap.DisplayMode() == EColor16MA);
       
   350     ASSERT(aSrcMaskBitmap.DisplayMode() == EGray2 || aSrcMaskBitmap.DisplayMode() == EGray256 || aSrcMaskBitmap.DisplayMode() == EGray16 || aSrcMaskBitmap.DisplayMode() == EGray4);
       
   351     // Resize the target bitmap if needed
       
   352     if (aSrcBitmap.SizeInPixels() != aCombinedBitmap.SizeInPixels())
       
   353         {
       
   354         aCombinedBitmap.Resize(aSrcBitmap.SizeInPixels());
       
   355         }
       
   356 /*
       
   357     CFbsDevice* targetdevice = NULL;
       
   358     CFbsBitGc* gc = NULL;
       
   359 
       
   360 
       
   361     // create device for drawing onto the target cropped bitmap area
       
   362     targetdevice = CFbsBitmapDevice::NewL(&aCombinedBitmap);
       
   363     CleanupStack::PushL(targetdevice);
       
   364     // create graphics context for drawing
       
   365     User::LeaveIfError(targetdevice->CreateContext(gc));
       
   366 
       
   367     // Make the target bitmap fully transparent
       
   368     gc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
       
   369     TRgb blank(KRgbWhite);
       
   370     blank.SetAlpha(255);
       
   371     gc->SetBrushColor(blank);
       
   372     gc->SetPenColor(blank);
       
   373     gc->Clear();
       
   374     gc->SetDrawMode(CGraphicsContext::EDrawModePEN);
       
   375 
       
   376     gc->BitBltMasked(TPoint(0,0),  // target pos
       
   377                      &aSrcBitmap,  // source bitmap
       
   378                      TRect(TPoint(0, 0),aSrcBitmap.SizeInPixels()), // source rect
       
   379                      &aSrcMaskBitmap,
       
   380                      EFalse);
       
   381 
       
   382     delete gc;
       
   383     CleanupStack::PopAndDestroy(targetdevice);
       
   384 */
       
   385     // Alternative method to blend manually (SLOW!!):
       
   386     // Apply the alpha mask.
       
   387     TBitmapUtil color((CFbsBitmap*)&aSrcBitmap);
       
   388     TBitmapUtil alpha((CFbsBitmap*)&aSrcMaskBitmap);
       
   389     TBitmapUtil target((CFbsBitmap*)&aCombinedBitmap);
       
   390     color.Begin(TPoint(0, 0));
       
   391     alpha.Begin(TPoint(0, 0));
       
   392     target.Begin(TPoint(0, 0));
       
   393     TSize size(aCombinedBitmap.SizeInPixels());
       
   394     for(TInt y = 0; y < size.iHeight; ++y)
       
   395         {
       
   396         alpha.SetPos(TPoint(0, y));
       
   397         color.SetPos(TPoint(0, y));
       
   398         target.SetPos(TPoint(0, y));
       
   399         for(TInt x = 0; x < size.iWidth; ++x)
       
   400             {
       
   401             target.SetPixel((color.GetPixel() & 0xffffff)
       
   402                           | ((alpha.GetPixel() & 0xff) << 24));
       
   403             target.IncXPos();
       
   404             color.IncXPos();
       
   405             alpha.IncXPos();
       
   406             }
       
   407         }
       
   408     target.End();
       
   409     color.End();
       
   410     alpha.End();
       
   411 
       
   412     }
       
   413 
       
   414 EXPORT_C void HuiUtil::CropFbsBitmapL(const CFbsBitmap & aSrcBitmap,
       
   415                                     CFbsBitmap & aCroppedBitmap,
       
   416                                     TPoint aCropPosition)
       
   417     {
       
   418     CFbsDevice* targetdevice;
       
   419     CFbsBitGc* gc;
       
   420     // create device for drawing onto the target cropped bitmap area
       
   421     targetdevice = CFbsBitmapDevice::NewL(&aCroppedBitmap);
       
   422     CleanupStack::PushL(targetdevice);
       
   423     // create graphics context for drawing
       
   424     User::LeaveIfError(targetdevice->CreateContext(gc));
       
   425     // Perform cropping bitblit
       
   426     gc->BitBlt(TPoint(0,0), &aSrcBitmap,
       
   427                TRect(aCropPosition, aCroppedBitmap.SizeInPixels()));
       
   428     delete gc;
       
   429     CleanupStack::PopAndDestroy(targetdevice);
       
   430     }
       
   431 
       
   432 EXPORT_C void HuiUtil::ScaleImage(TInt aComponents,
       
   433                                   const TSize& aSrcSize,
       
   434                                   const TUint8* aSrcBuffer,
       
   435                                   const TSize& aDestSize,
       
   436                                   TUint8* aDestBuffer)
       
   437     {
       
   438     // TODO: if there is actual use for this routine,
       
   439     // there might be better minification filters than bilinear...
       
   440     // anyway, now this routine produced acceptable results
       
   441     // when magnifying also...
       
   442     ASSERT (aDestBuffer && aSrcBuffer);
       
   443     ASSERT (aSrcSize.iWidth > 0 && aSrcSize.iHeight > 0);
       
   444     ASSERT (aDestSize.iWidth > 0 && aDestSize.iHeight > 0);
       
   445     ASSERT (aComponents > 0 && aComponents < 5);
       
   446 
       
   447     TUint32 xScale = ((aSrcSize.iWidth-1) << 16) / aDestSize.iWidth;
       
   448     TUint32 yScale = ((aSrcSize.iHeight-1) << 16) / aDestSize.iHeight;
       
   449     TUint32 height = aDestSize.iHeight;
       
   450     TUint8* srcptr = const_cast<TUint8*>(aSrcBuffer);
       
   451     TUint8* destPtrLimit = aDestBuffer+(aDestSize.iWidth*aComponents);
       
   452     TUint32 y = yScale&0xffff;
       
   453     do 
       
   454         {
       
   455         TUint32 fV = y&0xffff;
       
   456         TUint32 x = xScale&0xffff;
       
   457         while(aDestBuffer < destPtrLimit)
       
   458             {
       
   459 
       
   460             TUint32 fU = x&0xffff;
       
   461             for (TInt components = 0; components < aComponents; components++)
       
   462                 {
       
   463                 TUint32 componenta = srcptr[((x>>16)*aComponents)+components];
       
   464                 TUint32 componentb = srcptr[((x>>16)*aComponents)+aComponents+components];
       
   465                 TUint32 componentc = srcptr[((x>>16)*aComponents)+(aSrcSize.iWidth*aComponents)+components];
       
   466                 TUint32 componentd = srcptr[((x>>16)*aComponents)+(aSrcSize.iWidth*aComponents)+aComponents+components];
       
   467 
       
   468                 TUint32 componentf1 = (componenta+(((fU*((componentb-componenta)))>>16))) & 0xff;
       
   469                 TUint32 componentf2 = (componentc+(((fU*((componentd-componentc)))>>16))) & 0xff;
       
   470                 TUint32 finalcomponent = (componentf1+(((fV*((componentf2-componentf1)))>>16))) & 0xff;
       
   471                 *aDestBuffer++ = (TUint8)finalcomponent;
       
   472                 }
       
   473             x+=xScale;
       
   474             }
       
   475         y+=yScale;
       
   476         srcptr = const_cast<TUint8*>(aSrcBuffer)+((y>>16)*(aSrcSize.iWidth*aComponents));
       
   477         destPtrLimit+=aDestSize.iWidth*aComponents;
       
   478         }
       
   479     while (--height);
       
   480     }
       
   481 /*
       
   482 EXPORT_C void HuiUtil::ConvertFbsBitmap(const CFbsBitmap* aSrcBitmap,
       
   483                                   const CFbsBitmap* aSrcMaskBitmap,
       
   484                                   const TSize& aDestSize,
       
   485                                   TUint8* aDestBuffer)
       
   486     {
       
   487 
       
   488     TReal32 weight = 1.0;
       
   489     TReal32 totals[4] =
       
   490         {
       
   491         0.0, 0.0, 0.0, 0.0
       
   492         };
       
   493     TReal32 area;
       
   494     TInt  destY,destX;
       
   495     TInt  outindex;
       
   496 
       
   497     TInt  startX = 0, endX = 0, startY = 0, endY = 0;
       
   498     TReal32 leftOffset, rightOffset, topOffset, bottomOffset;
       
   499     TInt  convKernelSizeY,     convKernelSizeX;
       
   500     TReal32 convKernelSizeYFrac, convKernelSizeXFrac;
       
   501     TInt  x, y;
       
   502 
       
   503     ASSERT (aDestBuffer && aSrcBitmap);
       
   504 
       
   505     TSize aSrcSize = aSrcBitmap->SizeInPixels();
       
   506     TInt aComponents = (aSrcMaskBitmap != NULL) ? 4 : 3;
       
   507 
       
   508     ASSERT (aSrcSize.iWidth > 0 && aSrcSize.iHeight > 0);
       
   509     ASSERT (aDestSize.iWidth > 0 && aDestSize.iHeight > 0);
       
   510     ASSERT (aComponents > 0 && aComponents < 5);
       
   511     // Max aComponents in a format is 4, so...
       
   512 
       
   513     // NOTE: here we have to force the const bitmap to
       
   514     // non-const, since the iterator does not provide
       
   515     // a const version. However this should not be a problem
       
   516     // since the operations involved in this method are
       
   517     // strictly read-only.
       
   518     TBitmapUtil srcIterator((CFbsBitmap*)aSrcBitmap);
       
   519     TBitmapUtil srcMaskIterator((CFbsBitmap*)aSrcMaskBitmap);
       
   520 
       
   521 
       
   522     // if the source and destination sizes match,
       
   523     // just perform a direct copy
       
   524     if(aSrcSize == aDestSize)
       
   525         {
       
   526         TUint8* output = aDestBuffer;
       
   527         srcIterator.Begin(TPoint(0, 0));
       
   528         for(TInt y = 0; y < aDestSize.iHeight; ++y)
       
   529             {
       
   530             srcIterator.SetPos(TPoint(0,y));
       
   531             TUint8* output = aDestBuffer + aComponents*aDestSize.iWidth*y;
       
   532             if(aComponents == 3)
       
   533                 {
       
   534                 for(TInt x = 0; x < aDestSize.iWidth; x++, srcIterator.IncXPos())
       
   535                     {
       
   536                     TUint32 pixel = srcIterator.GetPixel();
       
   537                     *output++ = (pixel >> 16) & 0xff;
       
   538                     *output++ = (pixel >> 8) & 0xff;
       
   539                     *output++ = pixel & 0xff;
       
   540                     }
       
   541                 }
       
   542             else
       
   543                 {
       
   544                 // components == 4 and alpha channel must be excluded..
       
   545                 for(TInt x = 0; x < aDestSize.iWidth; x++, srcIterator.IncXPos())
       
   546                     {
       
   547                     TUint32 pixel = srcIterator.GetPixel();
       
   548                     *output++ = (pixel >> 16) & 0xff;
       
   549                     *output++ = (pixel >> 8) & 0xff;
       
   550                     *output++ = pixel & 0xff;
       
   551                     // skip alpha (expect the alpha value from the mask bitmap..
       
   552                     output++;
       
   553                     // alpha is not really supported by the
       
   554                     // scaling algorithm below. some small changes needed to implement..
       
   555                     // *output++ = pixel.Alpha();
       
   556                     }
       
   557                 }
       
   558 
       
   559             }
       
   560         srcIterator.End();
       
   561 
       
   562         // then integrate the alpha channel, if
       
   563         // provided
       
   564         if(aSrcMaskBitmap!=NULL)
       
   565             {
       
   566             srcMaskIterator.Begin(TPoint(0,0));
       
   567             for(TInt y = 0; y < aDestSize.iHeight; ++y)
       
   568                 {
       
   569                 srcMaskIterator.SetPos(TPoint(0,y));
       
   570                 TUint8* output = aDestBuffer + aComponents*aDestSize.iWidth*y + 3;
       
   571                 for(TInt x = 0;
       
   572                     x < aDestSize.iWidth;
       
   573                     x++, srcMaskIterator.IncXPos(), output += aComponents)
       
   574                     {
       
   575                     // The mask bitmap is in EGray256 format, which means the return
       
   576                     // values from TBitmapUtil::GetPixel() should be in range 0...255.
       
   577                     *output = srcMaskIterator.GetPixel() & 0xff;
       
   578                     }
       
   579                 }
       
   580             srcMaskIterator.End();
       
   581             }
       
   582         return;
       
   583         }
       
   584 
       
   585 
       
   586 
       
   587     /// @todo ScaleImaage may be optimized for halved cases, which is very common!
       
   588 
       
   589     // if (widthin == widthout*2 && heightin == heightout*2) {
       
   590     // halveImage_ubyte(aComponents, widthin, heightin,
       
   591     // (const GLubyte *)aSrcBuffer, (GLubyte *)dataout,
       
   592     // element_size, ysize, aComponents);
       
   593     // return;
       
   594     // }
       
   595 
       
   596     TReal32 convy = (TReal32)aSrcSize.iHeight/aDestSize.iHeight;
       
   597     TReal32 convx = (TReal32)aSrcSize.iWidth/aDestSize.iWidth;
       
   598     convKernelSizeY = (TInt)convy;
       
   599     convKernelSizeYFrac = convy - convKernelSizeY;
       
   600     convKernelSizeX = (TInt)convx;
       
   601     convKernelSizeXFrac = convx - convKernelSizeX;
       
   602 
       
   603     area = convx * convy;
       
   604 
       
   605     startY = 0;
       
   606     topOffset = 0;
       
   607     endY = convKernelSizeY;
       
   608     bottomOffset = convKernelSizeYFrac;
       
   609 
       
   610     TRgb pixel;
       
   611     // lock the bitmaps for fast access
       
   612     srcIterator.Begin(TPoint(0,0));
       
   613     if(aSrcMaskBitmap!=NULL)
       
   614         {
       
   615         srcMaskIterator.Begin(TPoint(0,0));
       
   616         }
       
   617 
       
   618 // define a helper macros for conveniently
       
   619 // accessing and summing pixels in a cfbsbitmap
       
   620 #define ADD_SINGLE_PIXEL_TOTALS(x, y, mul) \
       
   621 aSrcBitmap->GetPixel(pixel, TPoint(x, y)); \
       
   622 totals[0] += pixel.Red() * mul; \
       
   623 totals[1] += pixel.Green() * mul; \
       
   624 totals[2] += pixel.Blue() * mul; \
       
   625 if(aSrcMaskBitmap!=NULL) \
       
   626     { \
       
   627     aSrcMaskBitmap->GetPixel(pixel, TPoint(x, y)); \
       
   628     totals[3] += pixel.Gray256() * mul; \
       
   629     }
       
   630 
       
   631 // add totals with an iterator (rgb channels)
       
   632 #define ITER_ADD_PIXEL_TOTALS_RGB(mul) \
       
   633     pixel = TRgb(srcIterator.GetPixel()); \
       
   634     totals[0] += pixel.Red() * mul; \
       
   635     totals[1] += pixel.Green() * mul; \
       
   636     totals[2] += pixel.Blue() * mul;
       
   637 
       
   638 // add totals with an iterator (alpha channel)
       
   639 #define ITER_ADD_PIXEL_TOTALS_A(mul) \
       
   640     totals[3] += TRgb(srcMaskIterator.GetPixel()).Gray256() * mul;
       
   641 
       
   642 // add totals for a whole row
       
   643 #define ADD_ROW_TOTALS_RGBA(startX, startY, endX, weight) \
       
   644     srcIterator.SetPos(TPoint(startX,startY));
       
   645     for(x = startX; x < endX; x++, srcIterator.IncXPos())
       
   646         {
       
   647         ITER_ADD_PIXEL_TOTALS_RGB(weight);
       
   648         }
       
   649     if (aSrcMaskBitmap!=NULL) {
       
   650     srcMaskIterator.SetPos(TPoint(startX,startY));
       
   651     for(x = startX; x < endX; x++, srcMaskIterator.IncXPos())
       
   652         {
       
   653         ITER_ADD_PIXEL_TOTALS_A(weight);
       
   654         }
       
   655     }
       
   656 // add totals for a whole column
       
   657 #define ADD_COLUMN_TOTALS_RGBA(startY, startX, endY, weight) \
       
   658     srcIterator.SetPos(TPoint(startX,startY));
       
   659     for(y = startY; y < endY; y++, srcIterator.IncYPos())
       
   660         {
       
   661         ITER_ADD_PIXEL_TOTALS_RGB(weight);
       
   662         }
       
   663     if (aSrcMaskBitmap!=NULL) {
       
   664     srcMaskIterator.SetPos(TPoint(startX,startY));
       
   665     for(y = startY; y < endY; y++, srcMaskIterator.IncYPos())
       
   666         {
       
   667         ITER_ADD_PIXEL_TOTALS_A(weight);
       
   668         }
       
   669     }
       
   670 
       
   671 
       
   672 
       
   673     for (destY = 0; destY < aDestSize.iHeight; destY++)
       
   674         {
       
   675         startX = 0;
       
   676         leftOffset = 0;
       
   677         endX = convKernelSizeX;
       
   678         rightOffset = convKernelSizeXFrac;
       
   679         // ---- rowSizeBytes = aSrcSize.iWidth*aComponents; // actually: groups_per_line * aComponents
       
   680 
       
   681         for (destX = 0; destX < aDestSize.iWidth; destX++)
       
   682             {
       
   683 
       
   684             // Ok, now apply box filter to box that goes from (lowx, lowy)
       
   685             // to (highx, highy) on input data into this pixel on output
       
   686             // data.
       
   687             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
       
   688 
       
   689             // the usual case for minification:
       
   690             // downscale for both dimensions
       
   691             if((endY>startY) && (endX>startX))
       
   692                 {
       
   693                 // calculate the value for pixels in the top row..
       
   694 
       
   695                 // first pixel with partial contribution both from left and from the top
       
   696                 weight = (1-topOffset) * (1-leftOffset);
       
   697                 // sums pixel to totals
       
   698                 ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
       
   699 
       
   700                 // first row with y weighting (partial contribution from the top)
       
   701                 weight = (1-topOffset);
       
   702                 ADD_ROW_TOTALS_RGBA((startX+1), startY, endX, weight);
       
   703 
       
   704                 // last pixel with contribution from the top and the right
       
   705                 weight = (1-topOffset) * rightOffset;
       
   706                 ADD_SINGLE_PIXEL_TOTALS(endX, startY, weight);
       
   707 
       
   708                 // calculate the value for pixels in the last row ...
       
   709 
       
   710                 // bottom-left corner pixel
       
   711                 // first pixel: fractional weight contribution from the left and below
       
   712                 weight = bottomOffset * (1-leftOffset);
       
   713                 ADD_SINGLE_PIXEL_TOTALS(startX, endY, weight);
       
   714 
       
   715                 // bottom row pixels
       
   716                 weight = bottomOffset;
       
   717                 ADD_ROW_TOTALS_RGBA(startX+1, endY, endX, weight);
       
   718 
       
   719                 // bottom-right corner pixel
       
   720                 weight = bottomOffset * rightOffset;
       
   721                 ADD_SINGLE_PIXEL_TOTALS(endX, endY, weight);
       
   722 
       
   723                 // calculate the value for pixels at the left and the right
       
   724                 // edges..
       
   725                 ADD_COLUMN_TOTALS_RGBA(startY+1, endY, startX, (1-leftOffset));
       
   726                 ADD_COLUMN_TOTALS_RGBA(startY+1, endY, (endX-1), rightOffset);
       
   727 
       
   728                 }
       
   729             else if (endY > startY)  // only squeeze in y direction?
       
   730                 {
       
   731                 // we just need to handle the left edge pixels
       
   732 
       
   733                 // top-left corner pixel first
       
   734                 weight = (1-topOffset)*(rightOffset - leftOffset);
       
   735                 // ---- srcBufferCurrentPos = (const TUint8*)aSrcBuffer + srcXPositionInBytes + startY*rowSizeBytes;
       
   736                 ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
       
   737 
       
   738                 // left edge
       
   739                 weight = rightOffset - leftOffset;
       
   740                 ADD_COLUMN_TOTALS_RGBA((startY+1), endY, startX, weight);
       
   741 
       
   742                 // bottom-left corner pixel has two affecting weights: left edge weight and the bottom weight
       
   743                 weight = (rightOffset - leftOffset) * bottomOffset;
       
   744                 ADD_SINGLE_PIXEL_TOTALS(startX, endY, weight);
       
   745                 }
       
   746             else if (endX > startX) // only squeeze in x direction?
       
   747                 {
       
   748 
       
   749                 // we just need to handle the top edge pixels
       
   750 
       
   751                 // top-left corner pixel first
       
   752                 weight = (1-leftOffset)*(bottomOffset - topOffset);
       
   753                 // sums pixel to totals
       
   754                 ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
       
   755 
       
   756                 // top edge pixels
       
   757                 weight = bottomOffset - topOffset;
       
   758                 ADD_ROW_TOTALS_RGBA((startX+1), startY, endX, weight);
       
   759 
       
   760                 // top-right edge pixel
       
   761                 weight = (bottomOffset - topOffset) * rightOffset;
       
   762                 ADD_SINGLE_PIXEL_TOTALS(endX, startY, weight);
       
   763                 }
       
   764             else // only single pixel? (the top-right pixel)
       
   765                 {
       
   766                 // this pixel is at the all corners of the area, so
       
   767                 // all edge offsets affect to its weight
       
   768                 weight = (bottomOffset-topOffset)*(rightOffset-leftOffset);
       
   769                 ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
       
   770                 }
       
   771 
       
   772             // this is for the pixels in the body
       
   773             for (y = startY+1; y < endY; y++)
       
   774                 {
       
   775                 ADD_ROW_TOTALS_RGBA((startX+1), y, endX, 1.0f);
       
   776                 }
       
   777 
       
   778             outindex = (destX + (destY * aDestSize.iWidth)) * aComponents;
       
   779             for (TInt component = 0; component < aComponents; component++)
       
   780                 {
       
   781                 aDestBuffer[outindex + component] = totals[component]/area;
       
   782 
       
   783                 }
       
   784             // prepare new block in x direction to be filtered
       
   785             startX = endX;
       
   786             leftOffset = rightOffset;
       
   787             endX += convKernelSizeX;
       
   788             rightOffset += convKernelSizeXFrac;
       
   789             if(rightOffset > 1)
       
   790                 {
       
   791                 rightOffset -= 1.0;
       
   792                 endX++;
       
   793                 }
       
   794             } // for startX
       
   795 
       
   796         // prepare new row of blocks to be filtered
       
   797         startY = endY;
       
   798         topOffset = bottomOffset;
       
   799         endY += convKernelSizeY;
       
   800         bottomOffset += convKernelSizeYFrac;
       
   801         if(bottomOffset > 1)
       
   802             {
       
   803             bottomOffset -= 1.0;
       
   804             endY++;
       
   805             }
       
   806         } // for startY
       
   807 
       
   808     // unlock the bitmaps after usage
       
   809     srcIterator.End();
       
   810     if(aSrcMaskBitmap!=NULL)
       
   811         {
       
   812         srcMaskIterator.End();
       
   813         }
       
   814 
       
   815     }
       
   816 */
       
   817 
       
   818 EXPORT_C void HuiUtil::CropImage(TInt aComponents,
       
   819                                 const TSize& aSrcBufferSize,
       
   820                                 const TUint8* aSrcBuffer,
       
   821                                 const TPoint& aCropOffset,
       
   822                                 const TSize& aCroppedSize,
       
   823                                 TUint8* aDestBuffer)
       
   824     {
       
   825     ASSERT (aDestBuffer && aSrcBuffer);
       
   826     ASSERT (aSrcBufferSize.iWidth > 0 && aSrcBufferSize.iHeight > 0);
       
   827     ASSERT (aCroppedSize.iWidth > 0 && aCroppedSize.iHeight > 0);
       
   828     ASSERT (aCropOffset.iX < aSrcBufferSize.iWidth);
       
   829     ASSERT (aCropOffset.iY < aSrcBufferSize.iHeight);
       
   830     ASSERT (aComponents > 0 && aComponents < 5);
       
   831 
       
   832     TInt targetlinesize = aCroppedSize.iWidth*aComponents;
       
   833     TInt sourcelinesize = aSrcBufferSize.iWidth*aComponents;
       
   834     for (TInt y=0; y<aCroppedSize.iHeight; y++)
       
   835         {
       
   836         // copy line at a time..
       
   837         TAny * source = (TAny*)((const TUint8*)aSrcBuffer
       
   838                             + ((y+aCropOffset.iY)*sourcelinesize)
       
   839                             + (aCropOffset.iX * aComponents));
       
   840         TAny * target = (TAny*)((const TUint8*)aDestBuffer + (y*targetlinesize));
       
   841         memcpy(target, source, targetlinesize);
       
   842         }
       
   843 
       
   844     }
       
   845 
       
   846 EXPORT_C CFbsBitmap* HuiUtil::ConvertBitmapToDisplayModeLC( const CFbsBitmap& aBitmap, const TDisplayMode& aDisplaymode )
       
   847     {
       
   848     // Create target bitmap
       
   849     CFbsBitmap* targetBitmap = new CFbsBitmap();
       
   850     CleanupStack::PushL( targetBitmap );
       
   851     targetBitmap->Create( aBitmap.SizeInPixels(), aDisplaymode );
       
   852 
       
   853     // Create bitmap device for target rendering
       
   854     CFbsBitmapDevice* targetDevice = CFbsBitmapDevice::NewL( targetBitmap );
       
   855     CleanupStack::PushL( targetDevice );
       
   856 
       
   857     // Create bitmap graphics context
       
   858     CFbsBitGc* bitgc = CFbsBitGc::NewL();
       
   859     CleanupStack::PushL( bitgc );
       
   860     bitgc->Activate( targetDevice );
       
   861 
       
   862     // BitBlt the given bitmap to target device.
       
   863     bitgc->BitBlt( TPoint( 0, 0 ), &aBitmap );
       
   864 
       
   865     CleanupStack::PopAndDestroy( bitgc );
       
   866     CleanupStack::PopAndDestroy( targetDevice );
       
   867 
       
   868     return targetBitmap;
       
   869     }
       
   870 
       
   871 
       
   872 EXPORT_C TBool HuiUtil::TagMatches(const TDesC8& aTagsColonSeparated, const TDesC8& aTag)
       
   873     {
       
   874     TPtrC8 region = aTagsColonSeparated;
       
   875     TPtrC8 tag;
       
   876     TInt index = 0;
       
   877 
       
   878     if(!aTag.Length())
       
   879         {
       
   880         // No tag specified; doesn't match anything.
       
   881         return EFalse;
       
   882         }
       
   883 
       
   884     while(region.Length() > 0)
       
   885         {
       
   886         // Is there a colon in the region?
       
   887         index = region.Locate(TChar(KTagSeparator));
       
   888         if(index != KErrNotFound)
       
   889             {
       
   890             // A separator exists in the region.
       
   891             tag.Set(region.Left(index));
       
   892             region.Set(region.Right((region.Length() - index) - 1));
       
   893             }
       
   894         else
       
   895             {
       
   896             tag.Set(region);
       
   897             region.Set(region.Right(0));
       
   898             }
       
   899 
       
   900         if(!tag.Compare(aTag))
       
   901             {
       
   902             // Matches.
       
   903             return ETrue;
       
   904             }
       
   905         }
       
   906 
       
   907     // No match could be found.
       
   908     return EFalse;
       
   909     }
       
   910 
       
   911 TReal32 HuiUtil::CalculateScaleFactorFromScaleMode( 
       
   912         const THuiRealSize& aContainerSize,   
       
   913         const THuiRealSize& aContentSize,
       
   914         CHuiImageVisual::TScaleMode aScaleMode,
       
   915         TReal32 aInitialScale )
       
   916     {
       
   917     TReal32 scale = aInitialScale;
       
   918 
       
   919     // Scaling factor adjustment.
       
   920     if(aScaleMode == CHuiImageVisual::EScaleFitHeight)
       
   921         {
       
   922         TReal32 contentHeight = aContentSize.iHeight;
       
   923         if(contentHeight > 0)
       
   924             {
       
   925             scale *= aContainerSize.iHeight / contentHeight;
       
   926             }
       
   927         }
       
   928     else if(aScaleMode == CHuiImageVisual::EScaleFitWidth)
       
   929         {
       
   930         TReal32 contentWidth = aContentSize.iWidth;
       
   931         if(contentWidth > 0)
       
   932             {
       
   933             scale *= aContainerSize.iWidth / contentWidth;
       
   934             }
       
   935         }
       
   936     else if(aScaleMode == CHuiImageVisual::EScaleCover || 
       
   937             aScaleMode == CHuiImageVisual::EScaleFitInside)
       
   938         {
       
   939         TReal32 heightScale = scale;
       
   940         TReal32 contentHeight = aContentSize.iHeight;
       
   941         if(contentHeight > 0)
       
   942             {
       
   943             heightScale *= aContainerSize.iHeight / contentHeight;
       
   944             }
       
   945 
       
   946         TReal32 widthScale = scale;
       
   947         TReal32 contentWidth = aContentSize.iWidth;
       
   948         if(contentWidth > 0)
       
   949             {
       
   950             widthScale *= aContainerSize.iWidth / contentWidth;
       
   951             }
       
   952 
       
   953         if(aScaleMode == CHuiImageVisual::EScaleCover)
       
   954             {
       
   955             scale = Max(widthScale, heightScale);
       
   956             }
       
   957         else
       
   958             {
       
   959             scale = Min(widthScale, heightScale);
       
   960             }
       
   961         }
       
   962     else
       
   963         {
       
   964         // for PC lint
       
   965         }
       
   966     return scale;
       
   967     }
       
   968     
       
   969 EXPORT_C TBool HuiUtil::RealCompare( 
       
   970     TReal32 aCompare1, 
       
   971     TReal32 aCompare2, 
       
   972     TReal32 aEpsilon )
       
   973     {
       
   974     if ( Abs(aCompare1 - aCompare2) < aEpsilon )
       
   975         {
       
   976         return ETrue;
       
   977         }
       
   978     return EFalse;
       
   979     }
       
   980 
       
   981 EXPORT_C void HuiUtil::Assert(TBool aCondition)
       
   982     {
       
   983     // Assert that the passed condition is true.
       
   984     if (aCondition == EFalse)
       
   985         {
       
   986         // You can breakpoint here to trap asserts.
       
   987         ASSERT(EFalse);           
       
   988         }
       
   989     }
       
   990 
       
   991 EXPORT_C CFbsBitmap* HuiUtil::CopyBitmapL(const CFbsBitmap& aSrc)
       
   992     {
       
   993     CFbsBitmap* newBitmap = new (ELeave) CFbsBitmap();
       
   994     CleanupStack::PushL( newBitmap );
       
   995     User::LeaveIfError( newBitmap->Create( aSrc.SizeInPixels(), aSrc.DisplayMode() ) );
       
   996     CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( newBitmap );
       
   997     CleanupStack::PushL( dev );
       
   998     CFbsBitGc* gc = NULL;
       
   999     User::LeaveIfError( dev->CreateContext( gc ) );
       
  1000     CleanupStack::PushL( gc );
       
  1001     gc->BitBlt( TPoint(0,0), &aSrc );
       
  1002     CleanupStack::PopAndDestroy(2); // dev, gc        
       
  1003     CleanupStack::Pop(); // newBitmap
       
  1004     return newBitmap;
       
  1005     }
       
  1006 
       
  1007 EXPORT_C TInt HuiUtil::GetValueFromCentralRepository( const TUint32 aKey, TInt& aValue )
       
  1008     {
       
  1009     CRepository* centralRepository = NULL;    
       
  1010     TRAPD( error, centralRepository = CRepository::NewL( KCRUidUIAccelTK ) );
       
  1011     TInt result = 0;
       
  1012     if ( error == KErrNone )
       
  1013         {
       
  1014         error = centralRepository->Get( aKey, result );
       
  1015         }
       
  1016     delete centralRepository;
       
  1017     centralRepository = NULL;
       
  1018     if ( error == KErrNone )
       
  1019         {
       
  1020         aValue = result;
       
  1021         }
       
  1022     return error;
       
  1023     }