uiacceltk/hitchcock/Client/src/alfutil.cpp
changeset 0 15bf7259bb7c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/Client/src/alfutil.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,571 @@
+/*
+* Copyright (c) 2006 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:   Misc. utils
+*
+*/
+
+
+
+//
+// NOTE THAT THIS FILE IS ALMOST IDENTICAL WITH HUIUTIL.CPP !
+//
+// HuiUtil.h functions are not called from this file because we want alfclient.dll
+// to not have unnecessary (any) static dependencies to core toolkit hitchcock.dll 
+// (a.k.a huitk.dll, uiaccel.dll,...). There is no other reason to duplicate 
+// this code.
+//
+
+#include "alf/alfutil.h"
+#include "alf/alftimedvalue.h"
+
+#include <e32math.h>
+#include <hal.h>
+#include <AknUtils.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 AlfUtil::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 AlfUtil::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 AlfUtil::Interpolate(TReal32 aPos, TReal32 aMin, TReal32 aMax) __SOFTFP
+    {
+    aPos = Max(0.f, aPos);
+    aPos = Min(aPos, 1.f);
+    return (1 - aPos) * aMin + aPos * aMax;
+    }
+
+
+EXPORT_C void AlfUtil::WrapValue(TReal32& aValue, TReal32 aLow, TReal32 aHigh) __SOFTFP
+    {
+    TReal32 segments = 0;
+    TReal32 length = aHigh - aLow;
+
+    if(length <= 0)
+        {
+        aValue = aLow;
+        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 AlfUtil::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 AlfUtil::RandomReal(TReal32 aMin, TReal32 aMax) __SOFTFP
+    {
+    /** @todo  Could use Math::FRand(). */
+    TReal32 random = RandomInt(0, 10000000) / 10000000.0;
+    return aMin + (aMax - aMin) * random;
+    }
+
+
+EXPORT_C TUint AlfUtil::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 AlfUtil::ScreenSize()
+    {
+    TSize screenSize(320, 240);
+
+    AknLayoutUtils::LayoutMetricsSize(AknLayoutUtils::EScreen, screenSize);
+
+    return screenSize;
+    }
+
+
+EXPORT_C CFont* AlfUtil::NearestFontInTwipsL(const TFontSpec& aFontSpec)
+    {
+    /// @todo  Accessing the screen device during a display resizing event may
+    ///        result in a font that is suitable for the display size that
+    ///        was in use prior to the resize. Probably we should use
+    ///        AknLayoutUtils here.
+
+    CFont* font = NULL;
+    CWsScreenDevice* screenDev = CCoeEnv::Static()->ScreenDevice();
+    User::LeaveIfError( screenDev->GetNearestFontInTwips(font, aFontSpec) );
+    return font;
+    }
+
+
+EXPORT_C void AlfUtil::ReleaseFont(CFont* aFont)
+    {
+    CCoeEnv::Static()->ScreenDevice()->ReleaseFont(aFont);
+    }
+
+
+EXPORT_C TReal32 AlfUtil::LengthUnit() __SOFTFP
+    {
+    return Max(ScreenSize().iWidth, ScreenSize().iHeight) / KLengthUnitDivisor;
+    }
+
+
+EXPORT_C TReal32 AlfUtil::QuickLength(TAlfRealPoint& 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 AlfUtil::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 AlfUtil::QuickNormalize(TAlfRealPoint& aNormal)
+    {
+    TReal32 approxLength = QuickLength(aNormal);
+
+    if(approxLength > 0)
+        {
+        aNormal.iX /= approxLength;
+        aNormal.iY /= approxLength;
+        }
+    }
+
+
+EXPORT_C void AlfUtil::QuickNormalize(TReal32 aVector[3]) __SOFTFP
+    {
+    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 AlfUtil::CrossProduct(const TReal32 aA[3], const TReal32 aB[3],
+                                    TReal32 aProduct[3]) __SOFTFP
+    {
+    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 AlfUtil::NormalFromPoints(const TReal32 aPoints[3][3], TReal32 aNormal[3]) __SOFTFP
+    {
+    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 AlfUtil::ShadowMatrix(const TReal32 aPlanePoint[3],
+                                    const TReal32 aPlaneNormal[3],
+                                    const TReal32 aLightPos[4],
+                                    TReal32 aDestMat[16]) __SOFTFP
+    {
+    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 AlfUtil::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 AlfUtil::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->DrawBitmap(TRect(TPoint(0,0), aScaledBitmap.SizeInPixels()),
+                   (const CFbsBitmap *)&aSrcBitmap);
+    delete gc;
+    CleanupStack::PopAndDestroy(targetdevice);
+    }
+
+EXPORT_C void AlfUtil::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());
+        }
+
+    // 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 AlfUtil::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 AlfUtil::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 AlfUtil::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* AlfUtil::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 AlfUtil::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;
+    }
+
+
+void AlfUtil::Assert(TBool aCondition)
+    {
+    // Assert that the passed condition is true.
+    if (aCondition == EFalse)
+        {
+        // You can breakpoint here to trap asserts.
+        ASSERT(EFalse);           
+        }
+    }
+
+
+TInt AlfUtil::RoundFloatToInt(TReal32 aVal)
+	{
+	return (aVal < 0 ? (TInt)(aVal - 0.5f) : (TInt)(aVal + 0.5f));
+	}
+
+// ---------------------------------------------------------------------------
+// DEPRECATED: Gets the Avkon Skin TAknsItemID based on string version
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TAknsItemID AlfUtil::ThemeItemIdL( CAlfEnv& /*aEnv*/, const TDesC& /*aSkinId*/)
+    {
+	return KAknsIIDNone;
+    }