--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiUtil.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,1023 @@
+/*
+* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation for HuiUtil class, a collection of utility
+* routines for HUITK.
+*
+*/
+
+
+
+#include "uiacceltk/HuiUtil.h"
+#include "uiacceltk/HuiFont.h"
+#include "uiacceltk/HuiRealPoint.h"
+
+#include <e32math.h>
+#include <hal.h>
+#include <AknUtils.h>
+#include <AknFontSpecification.h>
+#include <AknFontAccess.h>
+#include <centralrepository.h>
+#include "uiacceltk/HuiDisplay.h"
+#include "../../CommonInc/uiacceltkdomaincrkeys.h"
+
+const TReal32 KLengthUnitDivisor = 320.0;
+
+/// Character used for separating tags in a tag descriptor.
+const TInt KTagSeparator = ':';
+
+
+// Calculates the smallest power-of-two that is equal to or greater than
+// a value.
+EXPORT_C TInt HuiUtil::Power2(TInt aValue)
+ {
+ ASSERT(aValue>0);
+ if(aValue<=0)
+ {
+ return 0;
+ }
+
+ TInt i;
+ for(i = 1; i < aValue && i < KMaxTInt/2; i *= 2)
+ {}
+ return i;
+ }
+
+EXPORT_C TInt HuiUtil::Power2RoundDown(TInt aValue)
+ {
+ ASSERT(aValue>0);
+ if(aValue <= 0)
+ {
+ return 0;
+ }
+
+ TInt i = 1;
+ for(; (i * 4 <= aValue) && (i < KMaxTInt/4); i *= 4)
+ {}
+ for(; (i * 2 <= aValue) && (i < KMaxTInt/2); i *= 2)
+ {}
+ return i;
+ }
+
+
+EXPORT_C TReal32 HuiUtil::Interpolate(TReal32 aPos, TReal32 aMin, TReal32 aMax) __SOFTFP
+ {
+ aPos = Max(0.f, aPos);
+ aPos = Min(aPos, 1.f);
+ return (1.f - aPos) * aMin + aPos * aMax;
+ }
+
+
+EXPORT_C void HuiUtil::WrapValue(TReal32& aValue, TReal32 aLow, TReal32 aHigh) __SOFTFP
+ {
+ TReal32 segments = 0;
+ TReal32 length = aHigh - aLow;
+
+ if(length <= 0)
+ {
+ aValue = aLow;
+ return;
+ }
+
+ // check rounding errors for low limit
+ if ( HuiUtil::RealCompare( aValue, aLow ) )
+ {
+ aValue = aLow;
+ return;
+ }
+
+ // check rounding errors for high limit
+ if ( HuiUtil::RealCompare( aValue, aHigh ) )
+ {
+ aValue = aHigh;
+ return;
+ }
+
+ if(aValue < aLow)
+ {
+ // Wrap from below.
+ segments = (aLow - aValue) / length;
+ aValue += (TInt(segments) + 1) * length;
+ }
+ else if(aValue >= aHigh)
+ {
+ // Wrap from above.
+ segments = (aValue - aHigh) / length;
+ aValue -= (TInt(segments) + 1) * length;
+ }
+ else
+ {
+ // for PC lint
+ }
+ }
+
+
+EXPORT_C TInt HuiUtil::RandomInt(TInt aMin, TInt aMax)
+ {
+ TUint32 random = Math::Random();
+ TUint range = aMax - aMin;
+ if(range > 0)
+ {
+ return aMin + (random % (range + 1));
+ }
+ else
+ {
+ return aMin;
+ }
+ }
+
+
+EXPORT_C TReal32 HuiUtil::RandomReal(TReal32 aMin, TReal32 aMax) __SOFTFP
+ {
+ /** @todo Could use Math::FRand(). */
+ TReal32 random = RandomInt(0, 10000000) / 10000000.f;
+ return aMin + (aMax - aMin) * random;
+ }
+
+
+EXPORT_C TUint HuiUtil::FreeMemory(TUint* aTotalMemory)
+ {
+ TInt total = 0;
+ TInt free = 0;
+
+ HAL::Get(HALData::EMemoryRAM, total);
+ HAL::Get(HALData::EMemoryRAMFree, free);
+ if(aTotalMemory)
+ {
+ *aTotalMemory = total;
+ }
+ return free;
+ }
+
+
+EXPORT_C TSize HuiUtil::ScreenSize()
+ {
+ TSize screenSize(320, 240);
+
+ if ( CCoeEnv::Static())
+ {
+ AknLayoutUtils::LayoutMetricsSize(AknLayoutUtils::EScreen, screenSize);
+ }
+ else
+ {
+ screenSize = CHuiStatic::ScreenDevice()->SizeInPixels();
+ }
+
+ return screenSize;
+ }
+
+
+EXPORT_C TReal32 HuiUtil::LengthUnit() __SOFTFP
+ {
+ return Max(ScreenSize().iWidth, ScreenSize().iHeight) / KLengthUnitDivisor;
+ }
+
+
+EXPORT_C TReal32 HuiUtil::QuickLength(THuiRealPoint& aVector) __SOFTFP
+ {
+ TReal32 dx = Abs(aVector.iX);
+ TReal32 dy = Abs(aVector.iY);
+ if(dx < dy)
+ {
+ return dx + dy - dx/2;
+ }
+ else
+ {
+ return dx + dy - dy/2;
+ }
+ }
+
+
+EXPORT_C TReal32 HuiUtil::QuickLength(TReal32 aDx, TReal32 aDy) __SOFTFP
+ {
+ TReal32 dx = Abs(aDx);
+ TReal32 dy = Abs(aDy);
+ if(dx < dy)
+ {
+ return dx + dy - dx/2;
+ }
+ else
+ {
+ return dx + dy - dy/2;
+ }
+ }
+
+
+EXPORT_C void HuiUtil::QuickNormalize(THuiRealPoint& aNormal)
+ {
+ TReal32 approxLength = QuickLength(aNormal);
+
+ if(approxLength > 0)
+ {
+ aNormal.iX /= approxLength;
+ aNormal.iY /= approxLength;
+ }
+ }
+
+
+EXPORT_C void HuiUtil::QuickNormalize(TReal32 aVector[3])
+ {
+ TReal32 approxLength = QuickLength(QuickLength(aVector[0], aVector[1]), aVector[2]);
+
+ if(approxLength > 0)
+ {
+ aVector[0] /= approxLength;
+ aVector[1] /= approxLength;
+ aVector[2] /= approxLength;
+ }
+ }
+
+
+EXPORT_C void HuiUtil::CrossProduct(const TReal32 aA[3], const TReal32 aB[3],
+ TReal32 aProduct[3])
+ {
+ aProduct[0] = aA[1] * aB[2] - aB[1] * aA[2];
+ aProduct[1] = aA[2] * aB[0] - aB[2] * aA[0];
+ aProduct[2] = aA[0] * aB[1] - aB[0] * aA[1];
+ }
+
+
+EXPORT_C void HuiUtil::NormalFromPoints(const TReal32 aPoints[3][3], TReal32 aNormal[3])
+ {
+ TReal32 vectors[2][3];
+ TInt i;
+
+ for(i = 0; i < 3; ++i)
+ {
+ vectors[0][i] = aPoints[0][i] - aPoints[1][i];
+ vectors[1][i] = aPoints[0][i] - aPoints[2][i];
+ }
+
+ CrossProduct(vectors[0], vectors[1], aNormal);
+ QuickNormalize(aNormal);
+ }
+
+
+EXPORT_C void HuiUtil::ShadowMatrix(const TReal32 aPlanePoint[3],
+ const TReal32 aPlaneNormal[3],
+ const TReal32 aLightPos[4],
+ TReal32 aDestMat[16])
+ {
+ TReal32 planeCoeff[4];
+ TReal32 dot;
+
+ // Find the plane equation coefficients
+ // Find the first three coefficients the same way we find a normal.
+ //NormalFromPoints(aPoints, planeCoeff);
+
+ planeCoeff[0] = aPlaneNormal[0];
+ planeCoeff[1] = aPlaneNormal[1];
+ planeCoeff[2] = aPlaneNormal[2];
+
+ // Find the last coefficient by back substitutions
+ planeCoeff[3] = - ((planeCoeff[0] * aPlanePoint[0]) + (planeCoeff[1] * aPlanePoint[1]) +
+ (planeCoeff[2] * aPlanePoint[2]));
+
+ // Dot product of plane and light position
+ dot = planeCoeff[0] * aLightPos[0] + planeCoeff[1] * aLightPos[1] +
+ planeCoeff[2] * aLightPos[2] + planeCoeff[3] * aLightPos[3];
+
+ // Now do the projection
+ // First column
+ aDestMat[0] = dot - aLightPos[0] * planeCoeff[0];
+ aDestMat[4] = 0.0f - aLightPos[0] * planeCoeff[1];
+ aDestMat[8] = 0.0f - aLightPos[0] * planeCoeff[2];
+ aDestMat[12] = 0.0f - aLightPos[0] * planeCoeff[3];
+
+ // Second column
+ aDestMat[1] = 0.0f - aLightPos[1] * planeCoeff[0];
+ aDestMat[5] = dot - aLightPos[1] * planeCoeff[1];
+ aDestMat[9] = 0.0f - aLightPos[1] * planeCoeff[2];
+ aDestMat[13] = 0.0f - aLightPos[1] * planeCoeff[3];
+
+ // Third Column
+ aDestMat[2] = 0.0f - aLightPos[2] * planeCoeff[0];
+ aDestMat[6] = 0.0f - aLightPos[2] * planeCoeff[1];
+ aDestMat[10] = dot - aLightPos[2] * planeCoeff[2];
+ aDestMat[14] = 0.0f - aLightPos[2] * planeCoeff[3];
+
+ // Fourth Column
+ aDestMat[3] = 0.0f - aLightPos[3] * planeCoeff[0];
+ aDestMat[7] = 0.0f - aLightPos[3] * planeCoeff[1];
+ aDestMat[11] = 0.0f - aLightPos[3] * planeCoeff[2];
+ aDestMat[15] = dot - aLightPos[3] * planeCoeff[3];
+ }
+
+
+EXPORT_C TReal32 HuiUtil::ColorLightness(const TRgb& aColor) __SOFTFP
+ {
+ TReal32 red = aColor.Red() / 255.0f;
+ TReal32 green = aColor.Red() / 255.0f;
+ TReal32 blue = aColor.Red() / 255.0f;
+
+ return (red*2 + green*3 + blue) / 6.f;
+ }
+
+EXPORT_C void HuiUtil::ScaleFbsBitmapL(const CFbsBitmap & aSrcBitmap,
+ CFbsBitmap & aScaledBitmap)
+ {
+ CFbsDevice* targetdevice = NULL;
+ CFbsBitGc* gc = NULL;
+ // create device for drawing onto the target cropped bitmap area
+ targetdevice = CFbsBitmapDevice::NewL(&aScaledBitmap);
+ CleanupStack::PushL(targetdevice);
+ // create graphics context for drawing
+ User::LeaveIfError(targetdevice->CreateContext(gc));
+ // Perform downscale using DrawBitmap
+ gc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+ gc->DrawBitmap(TRect(TPoint(0,0), aScaledBitmap.SizeInPixels()),
+ (const CFbsBitmap *)&aSrcBitmap);
+ delete gc;
+ CleanupStack::PopAndDestroy(targetdevice);
+ }
+
+EXPORT_C void HuiUtil::CombineMaskFbsBitmapL(const CFbsBitmap & aSrcBitmap,
+ const CFbsBitmap & aSrcMaskBitmap,
+ CFbsBitmap & aCombinedBitmap)
+ {
+
+ ASSERT(aCombinedBitmap.DisplayMode() == EColor16MA);
+ ASSERT(aSrcMaskBitmap.DisplayMode() == EGray2 || aSrcMaskBitmap.DisplayMode() == EGray256 || aSrcMaskBitmap.DisplayMode() == EGray16 || aSrcMaskBitmap.DisplayMode() == EGray4);
+ // Resize the target bitmap if needed
+ if (aSrcBitmap.SizeInPixels() != aCombinedBitmap.SizeInPixels())
+ {
+ aCombinedBitmap.Resize(aSrcBitmap.SizeInPixels());
+ }
+/*
+ CFbsDevice* targetdevice = NULL;
+ CFbsBitGc* gc = NULL;
+
+
+ // create device for drawing onto the target cropped bitmap area
+ targetdevice = CFbsBitmapDevice::NewL(&aCombinedBitmap);
+ CleanupStack::PushL(targetdevice);
+ // create graphics context for drawing
+ User::LeaveIfError(targetdevice->CreateContext(gc));
+
+ // Make the target bitmap fully transparent
+ gc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+ TRgb blank(KRgbWhite);
+ blank.SetAlpha(255);
+ gc->SetBrushColor(blank);
+ gc->SetPenColor(blank);
+ gc->Clear();
+ gc->SetDrawMode(CGraphicsContext::EDrawModePEN);
+
+ gc->BitBltMasked(TPoint(0,0), // target pos
+ &aSrcBitmap, // source bitmap
+ TRect(TPoint(0, 0),aSrcBitmap.SizeInPixels()), // source rect
+ &aSrcMaskBitmap,
+ EFalse);
+
+ delete gc;
+ CleanupStack::PopAndDestroy(targetdevice);
+*/
+ // Alternative method to blend manually (SLOW!!):
+ // Apply the alpha mask.
+ TBitmapUtil color((CFbsBitmap*)&aSrcBitmap);
+ TBitmapUtil alpha((CFbsBitmap*)&aSrcMaskBitmap);
+ TBitmapUtil target((CFbsBitmap*)&aCombinedBitmap);
+ color.Begin(TPoint(0, 0));
+ alpha.Begin(TPoint(0, 0));
+ target.Begin(TPoint(0, 0));
+ TSize size(aCombinedBitmap.SizeInPixels());
+ for(TInt y = 0; y < size.iHeight; ++y)
+ {
+ alpha.SetPos(TPoint(0, y));
+ color.SetPos(TPoint(0, y));
+ target.SetPos(TPoint(0, y));
+ for(TInt x = 0; x < size.iWidth; ++x)
+ {
+ target.SetPixel((color.GetPixel() & 0xffffff)
+ | ((alpha.GetPixel() & 0xff) << 24));
+ target.IncXPos();
+ color.IncXPos();
+ alpha.IncXPos();
+ }
+ }
+ target.End();
+ color.End();
+ alpha.End();
+
+ }
+
+EXPORT_C void HuiUtil::CropFbsBitmapL(const CFbsBitmap & aSrcBitmap,
+ CFbsBitmap & aCroppedBitmap,
+ TPoint aCropPosition)
+ {
+ CFbsDevice* targetdevice;
+ CFbsBitGc* gc;
+ // create device for drawing onto the target cropped bitmap area
+ targetdevice = CFbsBitmapDevice::NewL(&aCroppedBitmap);
+ CleanupStack::PushL(targetdevice);
+ // create graphics context for drawing
+ User::LeaveIfError(targetdevice->CreateContext(gc));
+ // Perform cropping bitblit
+ gc->BitBlt(TPoint(0,0), &aSrcBitmap,
+ TRect(aCropPosition, aCroppedBitmap.SizeInPixels()));
+ delete gc;
+ CleanupStack::PopAndDestroy(targetdevice);
+ }
+
+EXPORT_C void HuiUtil::ScaleImage(TInt aComponents,
+ const TSize& aSrcSize,
+ const TUint8* aSrcBuffer,
+ const TSize& aDestSize,
+ TUint8* aDestBuffer)
+ {
+ // TODO: if there is actual use for this routine,
+ // there might be better minification filters than bilinear...
+ // anyway, now this routine produced acceptable results
+ // when magnifying also...
+ ASSERT (aDestBuffer && aSrcBuffer);
+ ASSERT (aSrcSize.iWidth > 0 && aSrcSize.iHeight > 0);
+ ASSERT (aDestSize.iWidth > 0 && aDestSize.iHeight > 0);
+ ASSERT (aComponents > 0 && aComponents < 5);
+
+ TUint32 xScale = ((aSrcSize.iWidth-1) << 16) / aDestSize.iWidth;
+ TUint32 yScale = ((aSrcSize.iHeight-1) << 16) / aDestSize.iHeight;
+ TUint32 height = aDestSize.iHeight;
+ TUint8* srcptr = const_cast<TUint8*>(aSrcBuffer);
+ TUint8* destPtrLimit = aDestBuffer+(aDestSize.iWidth*aComponents);
+ TUint32 y = yScale&0xffff;
+ do
+ {
+ TUint32 fV = y&0xffff;
+ TUint32 x = xScale&0xffff;
+ while(aDestBuffer < destPtrLimit)
+ {
+
+ TUint32 fU = x&0xffff;
+ for (TInt components = 0; components < aComponents; components++)
+ {
+ TUint32 componenta = srcptr[((x>>16)*aComponents)+components];
+ TUint32 componentb = srcptr[((x>>16)*aComponents)+aComponents+components];
+ TUint32 componentc = srcptr[((x>>16)*aComponents)+(aSrcSize.iWidth*aComponents)+components];
+ TUint32 componentd = srcptr[((x>>16)*aComponents)+(aSrcSize.iWidth*aComponents)+aComponents+components];
+
+ TUint32 componentf1 = (componenta+(((fU*((componentb-componenta)))>>16))) & 0xff;
+ TUint32 componentf2 = (componentc+(((fU*((componentd-componentc)))>>16))) & 0xff;
+ TUint32 finalcomponent = (componentf1+(((fV*((componentf2-componentf1)))>>16))) & 0xff;
+ *aDestBuffer++ = (TUint8)finalcomponent;
+ }
+ x+=xScale;
+ }
+ y+=yScale;
+ srcptr = const_cast<TUint8*>(aSrcBuffer)+((y>>16)*(aSrcSize.iWidth*aComponents));
+ destPtrLimit+=aDestSize.iWidth*aComponents;
+ }
+ while (--height);
+ }
+/*
+EXPORT_C void HuiUtil::ConvertFbsBitmap(const CFbsBitmap* aSrcBitmap,
+ const CFbsBitmap* aSrcMaskBitmap,
+ const TSize& aDestSize,
+ TUint8* aDestBuffer)
+ {
+
+ TReal32 weight = 1.0;
+ TReal32 totals[4] =
+ {
+ 0.0, 0.0, 0.0, 0.0
+ };
+ TReal32 area;
+ TInt destY,destX;
+ TInt outindex;
+
+ TInt startX = 0, endX = 0, startY = 0, endY = 0;
+ TReal32 leftOffset, rightOffset, topOffset, bottomOffset;
+ TInt convKernelSizeY, convKernelSizeX;
+ TReal32 convKernelSizeYFrac, convKernelSizeXFrac;
+ TInt x, y;
+
+ ASSERT (aDestBuffer && aSrcBitmap);
+
+ TSize aSrcSize = aSrcBitmap->SizeInPixels();
+ TInt aComponents = (aSrcMaskBitmap != NULL) ? 4 : 3;
+
+ ASSERT (aSrcSize.iWidth > 0 && aSrcSize.iHeight > 0);
+ ASSERT (aDestSize.iWidth > 0 && aDestSize.iHeight > 0);
+ ASSERT (aComponents > 0 && aComponents < 5);
+ // Max aComponents in a format is 4, so...
+
+ // NOTE: here we have to force the const bitmap to
+ // non-const, since the iterator does not provide
+ // a const version. However this should not be a problem
+ // since the operations involved in this method are
+ // strictly read-only.
+ TBitmapUtil srcIterator((CFbsBitmap*)aSrcBitmap);
+ TBitmapUtil srcMaskIterator((CFbsBitmap*)aSrcMaskBitmap);
+
+
+ // if the source and destination sizes match,
+ // just perform a direct copy
+ if(aSrcSize == aDestSize)
+ {
+ TUint8* output = aDestBuffer;
+ srcIterator.Begin(TPoint(0, 0));
+ for(TInt y = 0; y < aDestSize.iHeight; ++y)
+ {
+ srcIterator.SetPos(TPoint(0,y));
+ TUint8* output = aDestBuffer + aComponents*aDestSize.iWidth*y;
+ if(aComponents == 3)
+ {
+ for(TInt x = 0; x < aDestSize.iWidth; x++, srcIterator.IncXPos())
+ {
+ TUint32 pixel = srcIterator.GetPixel();
+ *output++ = (pixel >> 16) & 0xff;
+ *output++ = (pixel >> 8) & 0xff;
+ *output++ = pixel & 0xff;
+ }
+ }
+ else
+ {
+ // components == 4 and alpha channel must be excluded..
+ for(TInt x = 0; x < aDestSize.iWidth; x++, srcIterator.IncXPos())
+ {
+ TUint32 pixel = srcIterator.GetPixel();
+ *output++ = (pixel >> 16) & 0xff;
+ *output++ = (pixel >> 8) & 0xff;
+ *output++ = pixel & 0xff;
+ // skip alpha (expect the alpha value from the mask bitmap..
+ output++;
+ // alpha is not really supported by the
+ // scaling algorithm below. some small changes needed to implement..
+ // *output++ = pixel.Alpha();
+ }
+ }
+
+ }
+ srcIterator.End();
+
+ // then integrate the alpha channel, if
+ // provided
+ if(aSrcMaskBitmap!=NULL)
+ {
+ srcMaskIterator.Begin(TPoint(0,0));
+ for(TInt y = 0; y < aDestSize.iHeight; ++y)
+ {
+ srcMaskIterator.SetPos(TPoint(0,y));
+ TUint8* output = aDestBuffer + aComponents*aDestSize.iWidth*y + 3;
+ for(TInt x = 0;
+ x < aDestSize.iWidth;
+ x++, srcMaskIterator.IncXPos(), output += aComponents)
+ {
+ // The mask bitmap is in EGray256 format, which means the return
+ // values from TBitmapUtil::GetPixel() should be in range 0...255.
+ *output = srcMaskIterator.GetPixel() & 0xff;
+ }
+ }
+ srcMaskIterator.End();
+ }
+ return;
+ }
+
+
+
+ /// @todo ScaleImaage may be optimized for halved cases, which is very common!
+
+ // if (widthin == widthout*2 && heightin == heightout*2) {
+ // halveImage_ubyte(aComponents, widthin, heightin,
+ // (const GLubyte *)aSrcBuffer, (GLubyte *)dataout,
+ // element_size, ysize, aComponents);
+ // return;
+ // }
+
+ TReal32 convy = (TReal32)aSrcSize.iHeight/aDestSize.iHeight;
+ TReal32 convx = (TReal32)aSrcSize.iWidth/aDestSize.iWidth;
+ convKernelSizeY = (TInt)convy;
+ convKernelSizeYFrac = convy - convKernelSizeY;
+ convKernelSizeX = (TInt)convx;
+ convKernelSizeXFrac = convx - convKernelSizeX;
+
+ area = convx * convy;
+
+ startY = 0;
+ topOffset = 0;
+ endY = convKernelSizeY;
+ bottomOffset = convKernelSizeYFrac;
+
+ TRgb pixel;
+ // lock the bitmaps for fast access
+ srcIterator.Begin(TPoint(0,0));
+ if(aSrcMaskBitmap!=NULL)
+ {
+ srcMaskIterator.Begin(TPoint(0,0));
+ }
+
+// define a helper macros for conveniently
+// accessing and summing pixels in a cfbsbitmap
+#define ADD_SINGLE_PIXEL_TOTALS(x, y, mul) \
+aSrcBitmap->GetPixel(pixel, TPoint(x, y)); \
+totals[0] += pixel.Red() * mul; \
+totals[1] += pixel.Green() * mul; \
+totals[2] += pixel.Blue() * mul; \
+if(aSrcMaskBitmap!=NULL) \
+ { \
+ aSrcMaskBitmap->GetPixel(pixel, TPoint(x, y)); \
+ totals[3] += pixel.Gray256() * mul; \
+ }
+
+// add totals with an iterator (rgb channels)
+#define ITER_ADD_PIXEL_TOTALS_RGB(mul) \
+ pixel = TRgb(srcIterator.GetPixel()); \
+ totals[0] += pixel.Red() * mul; \
+ totals[1] += pixel.Green() * mul; \
+ totals[2] += pixel.Blue() * mul;
+
+// add totals with an iterator (alpha channel)
+#define ITER_ADD_PIXEL_TOTALS_A(mul) \
+ totals[3] += TRgb(srcMaskIterator.GetPixel()).Gray256() * mul;
+
+// add totals for a whole row
+#define ADD_ROW_TOTALS_RGBA(startX, startY, endX, weight) \
+ srcIterator.SetPos(TPoint(startX,startY));
+ for(x = startX; x < endX; x++, srcIterator.IncXPos())
+ {
+ ITER_ADD_PIXEL_TOTALS_RGB(weight);
+ }
+ if (aSrcMaskBitmap!=NULL) {
+ srcMaskIterator.SetPos(TPoint(startX,startY));
+ for(x = startX; x < endX; x++, srcMaskIterator.IncXPos())
+ {
+ ITER_ADD_PIXEL_TOTALS_A(weight);
+ }
+ }
+// add totals for a whole column
+#define ADD_COLUMN_TOTALS_RGBA(startY, startX, endY, weight) \
+ srcIterator.SetPos(TPoint(startX,startY));
+ for(y = startY; y < endY; y++, srcIterator.IncYPos())
+ {
+ ITER_ADD_PIXEL_TOTALS_RGB(weight);
+ }
+ if (aSrcMaskBitmap!=NULL) {
+ srcMaskIterator.SetPos(TPoint(startX,startY));
+ for(y = startY; y < endY; y++, srcMaskIterator.IncYPos())
+ {
+ ITER_ADD_PIXEL_TOTALS_A(weight);
+ }
+ }
+
+
+
+ for (destY = 0; destY < aDestSize.iHeight; destY++)
+ {
+ startX = 0;
+ leftOffset = 0;
+ endX = convKernelSizeX;
+ rightOffset = convKernelSizeXFrac;
+ // ---- rowSizeBytes = aSrcSize.iWidth*aComponents; // actually: groups_per_line * aComponents
+
+ for (destX = 0; destX < aDestSize.iWidth; destX++)
+ {
+
+ // Ok, now apply box filter to box that goes from (lowx, lowy)
+ // to (highx, highy) on input data into this pixel on output
+ // data.
+ totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
+
+ // the usual case for minification:
+ // downscale for both dimensions
+ if((endY>startY) && (endX>startX))
+ {
+ // calculate the value for pixels in the top row..
+
+ // first pixel with partial contribution both from left and from the top
+ weight = (1-topOffset) * (1-leftOffset);
+ // sums pixel to totals
+ ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
+
+ // first row with y weighting (partial contribution from the top)
+ weight = (1-topOffset);
+ ADD_ROW_TOTALS_RGBA((startX+1), startY, endX, weight);
+
+ // last pixel with contribution from the top and the right
+ weight = (1-topOffset) * rightOffset;
+ ADD_SINGLE_PIXEL_TOTALS(endX, startY, weight);
+
+ // calculate the value for pixels in the last row ...
+
+ // bottom-left corner pixel
+ // first pixel: fractional weight contribution from the left and below
+ weight = bottomOffset * (1-leftOffset);
+ ADD_SINGLE_PIXEL_TOTALS(startX, endY, weight);
+
+ // bottom row pixels
+ weight = bottomOffset;
+ ADD_ROW_TOTALS_RGBA(startX+1, endY, endX, weight);
+
+ // bottom-right corner pixel
+ weight = bottomOffset * rightOffset;
+ ADD_SINGLE_PIXEL_TOTALS(endX, endY, weight);
+
+ // calculate the value for pixels at the left and the right
+ // edges..
+ ADD_COLUMN_TOTALS_RGBA(startY+1, endY, startX, (1-leftOffset));
+ ADD_COLUMN_TOTALS_RGBA(startY+1, endY, (endX-1), rightOffset);
+
+ }
+ else if (endY > startY) // only squeeze in y direction?
+ {
+ // we just need to handle the left edge pixels
+
+ // top-left corner pixel first
+ weight = (1-topOffset)*(rightOffset - leftOffset);
+ // ---- srcBufferCurrentPos = (const TUint8*)aSrcBuffer + srcXPositionInBytes + startY*rowSizeBytes;
+ ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
+
+ // left edge
+ weight = rightOffset - leftOffset;
+ ADD_COLUMN_TOTALS_RGBA((startY+1), endY, startX, weight);
+
+ // bottom-left corner pixel has two affecting weights: left edge weight and the bottom weight
+ weight = (rightOffset - leftOffset) * bottomOffset;
+ ADD_SINGLE_PIXEL_TOTALS(startX, endY, weight);
+ }
+ else if (endX > startX) // only squeeze in x direction?
+ {
+
+ // we just need to handle the top edge pixels
+
+ // top-left corner pixel first
+ weight = (1-leftOffset)*(bottomOffset - topOffset);
+ // sums pixel to totals
+ ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
+
+ // top edge pixels
+ weight = bottomOffset - topOffset;
+ ADD_ROW_TOTALS_RGBA((startX+1), startY, endX, weight);
+
+ // top-right edge pixel
+ weight = (bottomOffset - topOffset) * rightOffset;
+ ADD_SINGLE_PIXEL_TOTALS(endX, startY, weight);
+ }
+ else // only single pixel? (the top-right pixel)
+ {
+ // this pixel is at the all corners of the area, so
+ // all edge offsets affect to its weight
+ weight = (bottomOffset-topOffset)*(rightOffset-leftOffset);
+ ADD_SINGLE_PIXEL_TOTALS(startX, startY, weight);
+ }
+
+ // this is for the pixels in the body
+ for (y = startY+1; y < endY; y++)
+ {
+ ADD_ROW_TOTALS_RGBA((startX+1), y, endX, 1.0f);
+ }
+
+ outindex = (destX + (destY * aDestSize.iWidth)) * aComponents;
+ for (TInt component = 0; component < aComponents; component++)
+ {
+ aDestBuffer[outindex + component] = totals[component]/area;
+
+ }
+ // prepare new block in x direction to be filtered
+ startX = endX;
+ leftOffset = rightOffset;
+ endX += convKernelSizeX;
+ rightOffset += convKernelSizeXFrac;
+ if(rightOffset > 1)
+ {
+ rightOffset -= 1.0;
+ endX++;
+ }
+ } // for startX
+
+ // prepare new row of blocks to be filtered
+ startY = endY;
+ topOffset = bottomOffset;
+ endY += convKernelSizeY;
+ bottomOffset += convKernelSizeYFrac;
+ if(bottomOffset > 1)
+ {
+ bottomOffset -= 1.0;
+ endY++;
+ }
+ } // for startY
+
+ // unlock the bitmaps after usage
+ srcIterator.End();
+ if(aSrcMaskBitmap!=NULL)
+ {
+ srcMaskIterator.End();
+ }
+
+ }
+*/
+
+EXPORT_C void HuiUtil::CropImage(TInt aComponents,
+ const TSize& aSrcBufferSize,
+ const TUint8* aSrcBuffer,
+ const TPoint& aCropOffset,
+ const TSize& aCroppedSize,
+ TUint8* aDestBuffer)
+ {
+ ASSERT (aDestBuffer && aSrcBuffer);
+ ASSERT (aSrcBufferSize.iWidth > 0 && aSrcBufferSize.iHeight > 0);
+ ASSERT (aCroppedSize.iWidth > 0 && aCroppedSize.iHeight > 0);
+ ASSERT (aCropOffset.iX < aSrcBufferSize.iWidth);
+ ASSERT (aCropOffset.iY < aSrcBufferSize.iHeight);
+ ASSERT (aComponents > 0 && aComponents < 5);
+
+ TInt targetlinesize = aCroppedSize.iWidth*aComponents;
+ TInt sourcelinesize = aSrcBufferSize.iWidth*aComponents;
+ for (TInt y=0; y<aCroppedSize.iHeight; y++)
+ {
+ // copy line at a time..
+ TAny * source = (TAny*)((const TUint8*)aSrcBuffer
+ + ((y+aCropOffset.iY)*sourcelinesize)
+ + (aCropOffset.iX * aComponents));
+ TAny * target = (TAny*)((const TUint8*)aDestBuffer + (y*targetlinesize));
+ memcpy(target, source, targetlinesize);
+ }
+
+ }
+
+EXPORT_C CFbsBitmap* HuiUtil::ConvertBitmapToDisplayModeLC( const CFbsBitmap& aBitmap, const TDisplayMode& aDisplaymode )
+ {
+ // Create target bitmap
+ CFbsBitmap* targetBitmap = new CFbsBitmap();
+ CleanupStack::PushL( targetBitmap );
+ targetBitmap->Create( aBitmap.SizeInPixels(), aDisplaymode );
+
+ // Create bitmap device for target rendering
+ CFbsBitmapDevice* targetDevice = CFbsBitmapDevice::NewL( targetBitmap );
+ CleanupStack::PushL( targetDevice );
+
+ // Create bitmap graphics context
+ CFbsBitGc* bitgc = CFbsBitGc::NewL();
+ CleanupStack::PushL( bitgc );
+ bitgc->Activate( targetDevice );
+
+ // BitBlt the given bitmap to target device.
+ bitgc->BitBlt( TPoint( 0, 0 ), &aBitmap );
+
+ CleanupStack::PopAndDestroy( bitgc );
+ CleanupStack::PopAndDestroy( targetDevice );
+
+ return targetBitmap;
+ }
+
+
+EXPORT_C TBool HuiUtil::TagMatches(const TDesC8& aTagsColonSeparated, const TDesC8& aTag)
+ {
+ TPtrC8 region = aTagsColonSeparated;
+ TPtrC8 tag;
+ TInt index = 0;
+
+ if(!aTag.Length())
+ {
+ // No tag specified; doesn't match anything.
+ return EFalse;
+ }
+
+ while(region.Length() > 0)
+ {
+ // Is there a colon in the region?
+ index = region.Locate(TChar(KTagSeparator));
+ if(index != KErrNotFound)
+ {
+ // A separator exists in the region.
+ tag.Set(region.Left(index));
+ region.Set(region.Right((region.Length() - index) - 1));
+ }
+ else
+ {
+ tag.Set(region);
+ region.Set(region.Right(0));
+ }
+
+ if(!tag.Compare(aTag))
+ {
+ // Matches.
+ return ETrue;
+ }
+ }
+
+ // No match could be found.
+ return EFalse;
+ }
+
+TReal32 HuiUtil::CalculateScaleFactorFromScaleMode(
+ const THuiRealSize& aContainerSize,
+ const THuiRealSize& aContentSize,
+ CHuiImageVisual::TScaleMode aScaleMode,
+ TReal32 aInitialScale )
+ {
+ TReal32 scale = aInitialScale;
+
+ // Scaling factor adjustment.
+ if(aScaleMode == CHuiImageVisual::EScaleFitHeight)
+ {
+ TReal32 contentHeight = aContentSize.iHeight;
+ if(contentHeight > 0)
+ {
+ scale *= aContainerSize.iHeight / contentHeight;
+ }
+ }
+ else if(aScaleMode == CHuiImageVisual::EScaleFitWidth)
+ {
+ TReal32 contentWidth = aContentSize.iWidth;
+ if(contentWidth > 0)
+ {
+ scale *= aContainerSize.iWidth / contentWidth;
+ }
+ }
+ else if(aScaleMode == CHuiImageVisual::EScaleCover ||
+ aScaleMode == CHuiImageVisual::EScaleFitInside)
+ {
+ TReal32 heightScale = scale;
+ TReal32 contentHeight = aContentSize.iHeight;
+ if(contentHeight > 0)
+ {
+ heightScale *= aContainerSize.iHeight / contentHeight;
+ }
+
+ TReal32 widthScale = scale;
+ TReal32 contentWidth = aContentSize.iWidth;
+ if(contentWidth > 0)
+ {
+ widthScale *= aContainerSize.iWidth / contentWidth;
+ }
+
+ if(aScaleMode == CHuiImageVisual::EScaleCover)
+ {
+ scale = Max(widthScale, heightScale);
+ }
+ else
+ {
+ scale = Min(widthScale, heightScale);
+ }
+ }
+ else
+ {
+ // for PC lint
+ }
+ return scale;
+ }
+
+EXPORT_C TBool HuiUtil::RealCompare(
+ TReal32 aCompare1,
+ TReal32 aCompare2,
+ TReal32 aEpsilon )
+ {
+ if ( Abs(aCompare1 - aCompare2) < aEpsilon )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+EXPORT_C void HuiUtil::Assert(TBool aCondition)
+ {
+ // Assert that the passed condition is true.
+ if (aCondition == EFalse)
+ {
+ // You can breakpoint here to trap asserts.
+ ASSERT(EFalse);
+ }
+ }
+
+EXPORT_C CFbsBitmap* HuiUtil::CopyBitmapL(const CFbsBitmap& aSrc)
+ {
+ CFbsBitmap* newBitmap = new (ELeave) CFbsBitmap();
+ CleanupStack::PushL( newBitmap );
+ User::LeaveIfError( newBitmap->Create( aSrc.SizeInPixels(), aSrc.DisplayMode() ) );
+ CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( newBitmap );
+ CleanupStack::PushL( dev );
+ CFbsBitGc* gc = NULL;
+ User::LeaveIfError( dev->CreateContext( gc ) );
+ CleanupStack::PushL( gc );
+ gc->BitBlt( TPoint(0,0), &aSrc );
+ CleanupStack::PopAndDestroy(2); // dev, gc
+ CleanupStack::Pop(); // newBitmap
+ return newBitmap;
+ }
+
+EXPORT_C TInt HuiUtil::GetValueFromCentralRepository( const TUint32 aKey, TInt& aValue )
+ {
+ CRepository* centralRepository = NULL;
+ TRAPD( error, centralRepository = CRepository::NewL( KCRUidUIAccelTK ) );
+ TInt result = 0;
+ if ( error == KErrNone )
+ {
+ error = centralRepository->Get( aKey, result );
+ }
+ delete centralRepository;
+ centralRepository = NULL;
+ if ( error == KErrNone )
+ {
+ aValue = result;
+ }
+ return error;
+ }