uiacceltk/hitchcock/coretoolkit/src/HuiGc.cpp
changeset 0 15bf7259bb7c
child 8 10534483575f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiGc.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,829 @@
+/*
+* 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 CHuiGc (graphics context) class.
+*
+*/
+
+
+
+#include "uiacceltk/HuiGc.h"  // Class definition
+#include "HuiRenderPlugin.h"
+#include "uiacceltk/HuiSegmentedTexture.h"
+#include "uiacceltk/HuiTextMesh.h"
+#include "uiacceltk/HuiFont.h"
+#include "uiacceltk/HuiImage.h"
+#include "uiacceltk/HuiTransformation.h"
+#include "uiacceltk/HuiPanic.h"
+#include "uiacceltk/HuiUtil.h"  // For hui assert.
+#include "uiacceltk/HuiTransformation.h"
+
+#include <e32math.h>
+#include <AknUtils.h>
+
+const TInt KHuiMaxRecycledRegionCount = 20;
+
+/** Default offset from the Z=0 plane (which 2D projection uses) to the
+    eyepoint, in 3D projection mode. */
+LOCAL_D const TReal32 KDefaultOffset2D = 1199.0;
+
+
+EXPORT_C CHuiGc::CHuiGc()
+        : iOrientation(EOrientationNormal),
+          iNearClipDistance(20.f),
+          iFarClipDistance(10000.f),
+          iFovFactor(1.f),
+          iPenColor(TRgb(255, 255, 255)), iPenAlpha(255),
+          iAlignHorizontal(EHuiAlignHLeft), iAlignVertical(EHuiAlignVTop),
+          iFrustumOffsetCompleteness(1.f),
+          iQuality(EHuiQualityAccurate),
+          iClipRegionStackCount(0)
+    {
+    /// @todo  Fix this: The real default is 1.f, but the application should
+    ///        be able to adjust the completeness. Wowidle/Mmenu have been
+    ///        developed with .666f.
+    iFrustumOffsetCompleteness = .666f;
+    }
+
+EXPORT_C CHuiGc::~CHuiGc()
+    {
+    iTempRegion.Close();
+    iClipRegion.Close();
+    iClipRegionStack.Reset();
+    iRecycledRegions.ResetAndDestroy();    
+    iWindowTransform = NULL;
+    iCurrentFont = NULL;
+    }
+
+
+EXPORT_C void CHuiGc::SetQuality(THuiQuality aQuality)
+    {
+    iQuality = aQuality;
+    }
+
+
+EXPORT_C THuiQuality CHuiGc::Quality() const
+    {
+    return iQuality;
+    }
+
+
+EXPORT_C void CHuiGc::SetDisplayArea(const TRect& aDisplayArea)
+    {
+    iDisplayArea = aDisplayArea;
+    iClipRegion.Clear();
+    iClipRegion.AddRect(aDisplayArea);
+    }
+
+
+EXPORT_C TRect CHuiGc::DisplayArea() const
+    {
+    if(iOrientation == EOrientationNormal)
+        {
+        return iDisplayArea;
+        }
+    else
+        {
+        TInt width = iDisplayArea.Width();
+        TInt height = iDisplayArea.Height();
+        /// @todo  Should not always be at the top left corner.
+        TRect rect(TPoint(0, 0), TSize(height, width));
+        return rect;
+        }
+    }
+
+
+EXPORT_C void CHuiGc::SetOrientation(TOrientation aOrientation)
+    {
+    iOrientation = aOrientation;
+    }
+
+
+EXPORT_C CHuiGc::TOrientation CHuiGc::Orientation() const
+    {
+    return iOrientation;
+    }
+
+
+EXPORT_C void CHuiGc::SetProjection(TProjection aProjection)
+    {
+    SetProjection(aProjection, iDisplayArea);
+    }
+
+
+EXPORT_C CHuiGc::TProjection CHuiGc::Projection() const
+    {
+    return iProjection;
+    }
+
+
+EXPORT_C void CHuiGc::SetProjection(TProjection aProjection, const TRect& aViewport)
+    {
+    iProjection = aProjection;
+    iProjectionViewport = aViewport;
+    iFrustumOffset = THuiRealPoint(0.f, 0.f);
+
+    UpdateProjection();
+    }
+
+
+EXPORT_C void CHuiGc::SetFrustumOffset(const THuiRealPoint& aFrustumOffset)
+    {
+    if(!iDisplayArea.Width() || !iDisplayArea.Height())
+        {
+        return;
+        }
+
+    THuiRealPoint local = aFrustumOffset;
+    TRect area = DisplayArea(); // Orientation applied.
+    local.iX -= area.Width()/2.f;
+    local.iY -= area.Height()/2.f;
+    local.iX /= area.Width()/2.f;
+    local.iY /= area.Height()/2.f;
+
+    // Adjust so that the perspective correction isn't complete.
+    local.iX *= iFrustumOffsetCompleteness;
+    local.iY *= iFrustumOffsetCompleteness;
+
+    iFrustumOffset = local;
+
+    UpdateProjection();
+    }
+
+
+EXPORT_C void CHuiGc::Disable(TFeature aFeature)
+    {
+    Enable(aFeature, EFalse);
+    }
+
+
+EXPORT_C TRect CHuiGc::UnOrientRect(const TRect& aOrientedRect) const
+    {
+    if(iOrientation == EOrientationCCW90)
+        {
+        // Un-orient 90 degrees clockwise.
+        TSize size(aOrientedRect.Height(), aOrientedRect.Width());
+        TPoint pos(iDisplayArea.Width() - aOrientedRect.iBr.iY,
+                   aOrientedRect.iTl.iX);
+        return TRect(pos, size);
+        }
+    else if(iOrientation == EOrientationCW90)
+        {
+        // Un-orient 90 degrees counterclockwise.
+        TSize size(aOrientedRect.Height(), aOrientedRect.Width());
+        TPoint pos(aOrientedRect.iTl.iY,
+                   iDisplayArea.Height() - aOrientedRect.iBr.iX);
+        return TRect(pos, size);
+        }
+    else
+        {
+        // No change because there is no orientation.
+        return aOrientedRect;
+        }
+    }
+
+EXPORT_C void CHuiGc::UnOrientRegion(TRegion& aOrientedRegion) const
+    {
+    if(iOrientation == EOrientationCCW90 || iOrientation == EOrientationCW90)
+        {
+        iTempRegion.Clear();
+        for (TInt i=0; i < aOrientedRegion.Count(); i++)
+            {
+            iTempRegion.AddRect(UnOrientRect(aOrientedRegion[i]));
+            }        
+        aOrientedRegion.Copy(iTempRegion);
+        }
+    else
+        {
+        // No change because there is no orientation.
+        }
+    }
+
+EXPORT_C void CHuiGc::PushClip()
+    {
+    RRegion* newRegion = CreateRecycledRegion();
+    
+    if (newRegion)
+        {
+        newRegion->Copy(iClipRegion);
+        iClipRegionStack.Append(newRegion);    
+        }
+        
+    // Out of memory situation is handled by keeping separate
+    // counter which is checked at pop.   
+    iClipRegionStackCount++;
+    }
+
+EXPORT_C void CHuiGc::PopClip()
+    {
+    __ASSERT_ALWAYS(iClipRegionStack.Count() > 0,
+                    THuiPanic::Panic(THuiPanic::EGcClipStackPopFromEmpty));
+
+    // Check if out of memory situation has happened in the push, so we don't pop
+    // because we have not really pushed anything.  
+    if (iClipRegionStackCount > iClipRegionStack.Count())
+        {
+        iClipRegionStackCount--;    
+        return;
+        }
+
+    if(iClipRegionStack.Count() > 0)
+        {
+        TInt index = iClipRegionStack.Count() - 1;
+        SetClipRegion(*iClipRegionStack[index]);        
+        RRegion* region = iClipRegionStack[index];        
+        iClipRegionStack.Remove(index);
+        DeleteRecycledRegion(region);
+        region = NULL;
+        iClipRegionStackCount--;    
+        }
+    }
+
+EXPORT_C void CHuiGc::SetClip(const TRect& aClipRect)
+    {
+    HUI_ASSERT(aClipRect.Width() >= 0);
+    HUI_ASSERT(aClipRect.Height() >= 0);    
+    
+    iTempRegion.Clear();
+    iTempRegion.AddRect(aClipRect);    
+    CHuiGc::SetClipRegion(iTempRegion);
+    }
+
+EXPORT_C TRect CHuiGc::ClipRect() const
+    {
+    // This does not really provide actually valid data anymore
+    // since clipping is done with a region. 
+    return iClipRegion.BoundingRect();
+    }
+
+const TRegion& CHuiGc::ClipRegion() const
+    {
+    return iClipRegion;
+    }
+
+
+EXPORT_C void CHuiGc::Clip(const TRect& aClipRect)
+    {
+    HUI_ASSERT(aClipRect.Width() >= 0);
+    HUI_ASSERT(aClipRect.Height() >= 0);
+    
+    if(iClipRegion.Intersects(aClipRect))
+        {
+        iTempRegion.Clear();
+        iTempRegion.AddRect(aClipRect);
+        iClipRegion.Intersect(iTempRegion);
+        }
+    else
+        {
+        // Empty clipping rectangle.
+        iClipRegion.Clear();
+        }
+    
+    SetClipRegion(iClipRegion);        
+    }
+
+EXPORT_C void CHuiGc::Clip(const TRegion& aClipRegion)
+    {
+    iClipRegion.Intersect(aClipRegion);
+    SetClipRegion(iClipRegion);
+    }
+    
+EXPORT_C void CHuiGc::SetClipRegion(const TRegion& aClipRegion)
+	{
+	if (&aClipRegion != &iClipRegion)
+	    {
+	    iClipRegion.Copy(aClipRegion);        
+	    }
+	}
+	
+EXPORT_C void CHuiGc::CancelClipping()
+    {
+    }
+
+EXPORT_C TInt CHuiGc::ClipStackCount() const
+    {
+    return iClipRegionStack.Count();
+    }
+
+
+EXPORT_C void CHuiGc::SetAlign(THuiAlignHorizontal aHorizontalAlign,
+                               THuiAlignVertical aVerticalAlign)
+    {
+    switch(aHorizontalAlign)
+        {
+        case EHuiAlignHLocale:
+            iAlignHorizontal = LocaleTextAlignment();
+            break;
+
+        case EHuiAlignHLocaleMirrored:
+            iAlignHorizontal = LocaleTextAlignment();
+            if(iAlignHorizontal == EHuiAlignHLeft)
+                {
+                iAlignHorizontal = EHuiAlignHRight;
+                }
+            else
+                {
+                iAlignHorizontal = EHuiAlignHLeft;
+                }
+            break;
+
+        default:
+            iAlignHorizontal = aHorizontalAlign;
+            break;
+        }
+
+    iAlignVertical = aVerticalAlign;
+    }
+
+
+EXPORT_C THuiAlignHorizontal CHuiGc::AlignHorizontal() const
+    {
+    return iAlignHorizontal;
+    }
+
+
+EXPORT_C THuiAlignVertical CHuiGc::AlignVertical() const
+    {
+    return iAlignVertical;
+    }
+
+
+EXPORT_C void CHuiGc::SetPenColor(const TRgb& aColor)
+    {
+    iPenColor = aColor;
+    }
+
+
+EXPORT_C TRgb CHuiGc::PenColor() const
+    {
+    return iPenColor;
+    }
+
+
+EXPORT_C void CHuiGc::SetPenColorAlpha(const TRgb& aColor)
+    {
+    iPenColor = aColor;
+    iPenColor.SetAlpha(255);
+
+    iPenAlpha = TUint8(aColor.Alpha()); // 8 bits should be enough
+    }
+
+
+EXPORT_C TRgb CHuiGc::PenColorAlpha() const
+    {
+    TRgb color = iPenColor;
+    color.SetAlpha(iPenAlpha);
+    return color;
+    }
+
+
+EXPORT_C void CHuiGc::SetPenAlpha(TInt aAlpha)
+    {
+    if(aAlpha < 0)
+        {
+        aAlpha = 0;
+        }
+    else if(aAlpha > 255)
+        {
+        aAlpha = 255;
+        }
+    else
+        {
+        // for PC lint
+        }
+    iPenAlpha = TUint8(aAlpha); // 8 bits should be enough
+    }
+
+
+EXPORT_C TInt CHuiGc::PenAlpha() const
+    {
+    return iPenAlpha;
+    }
+
+
+EXPORT_C void CHuiGc::SetFont(THuiFont& aFont)
+    {
+    iCurrentFont = &aFont;
+    }
+
+
+EXPORT_C void CHuiGc::DrawTextL(const TDesC& aText,
+                                const THuiRealRect& aBounds,
+                                TReal32 aShadow) __SOFTFP
+    {
+    if(!Font())
+        {
+        return;
+        }
+    CHuiTextMesh* mesh = CHuiStatic::Renderer().CreateTextMeshL();
+    CleanupStack::PushL(mesh);
+    mesh->SetTextL(aText, ETrue);
+    DrawText(*mesh, aBounds, aShadow);
+    CleanupStack::PopAndDestroy(mesh);
+    }
+
+
+EXPORT_C void CHuiGc::DrawText(const CHuiTextMesh& aTextMesh,
+                               const THuiRealRect& aBounds,
+                               TReal32 aShadow) __SOFTFP
+    {
+    /** @todo  This could be generalized: MHuiBoundedDrawable (for example) */
+
+    // Font is defined in the text mesh.
+
+    // Real bounding size of the text.
+    TSize textBounds = aTextMesh.Extents();
+
+    // Reference origin for the text.
+    TPoint offset = AlignOffset(aBounds.Size());
+
+    // Actual starting point for glyphs.
+    THuiRealPoint pos = aBounds.iTl - offset;
+    switch(AlignHorizontal())
+        {
+        case EHuiAlignHRight:
+            pos.iX -= textBounds.iWidth;
+            break;
+
+        case EHuiAlignHCenter:
+            pos.iX -= textBounds.iWidth / 2; // or 2.f?
+            break;
+
+        default:
+            break;
+        }
+    switch(AlignVertical())
+        {
+        case EHuiAlignVBottom:
+            pos.iY -= textBounds.iHeight;
+            break;
+
+        case EHuiAlignVCenter:
+            pos.iY -= textBounds.iHeight / 2; // or 2.f?
+            break;
+
+        default:
+            break;
+        }
+
+
+    // Apply the position.
+    Push(EHuiGcMatrixModel);
+    Translate(EHuiGcMatrixModel, pos.iX, pos.iY, 0.f);
+
+    aTextMesh.Draw(*this, aShadow);
+
+    Pop(EHuiGcMatrixModel);
+    }
+
+
+EXPORT_C void CHuiGc::DrawImage(const THuiImage& aImage,
+                                const THuiRealPoint& aPos,
+                                const THuiRealSize& aSize)
+    {
+    if(!aImage.HasTexture())
+        {
+        return;
+        }
+
+    THuiRealPoint topLeft = aPos + AlignOffset(aSize);
+    UpdateColor();
+
+    // Update texture preferred size, toolkit may use this information to resize texture
+    NotifyImagePreferredSize(aImage, THuiRealRect(topLeft,aSize));
+    
+    DoDrawImage(aImage, topLeft, aSize);
+    }
+
+
+EXPORT_C void CHuiGc::DrawImages(const THuiImage& aImage,
+                                 const THuiImage& aImage2,
+                                 const THuiRealPoint& aPos,
+                                 const THuiRealSize& aSize)
+    {
+    if(!aImage.HasTexture() || !aImage2.HasTexture())
+        {
+        return;
+        }
+
+    THuiRealPoint topLeft = aPos + AlignOffset(aSize);
+    UpdateColor();
+    
+    // Update texture preferred size, toolkit may use this information to resize texture
+    NotifyImagePreferredSize(aImage, THuiRealRect(topLeft,aSize));
+    NotifyImagePreferredSize(aImage2, THuiRealRect(topLeft,aSize));
+
+    DoDrawImages(aImage, aImage2, topLeft, aSize);
+    }
+
+
+EXPORT_C void CHuiGc::DrawImage(const THuiImage& aImage,
+                                const THuiRealRect& aBounds)
+    {
+    if(!aImage.HasTexture())
+        {
+        return;
+        }
+
+    TSize space(TInt(aBounds.Width() - aImage.Texture().Size().iWidth),
+                TInt(aBounds.Height() - aImage.Texture().Size().iHeight));
+
+    TPoint topLeft = aBounds.iTl - AlignOffset(space);
+
+    UpdateColor();
+
+    // Update texture preferred size, toolkit may use this information to resize texture
+    NotifyImagePreferredSize(aImage, aBounds);
+
+    DoDrawImage(aImage, topLeft, aImage.Texture().Size());
+    }
+
+
+EXPORT_C void CHuiGc::DrawImage( const THuiImage& aImage,
+                                 const THuiRealSize& aSize,
+                                 const THuiRealRect& aBounds)
+    {
+    if(!aImage.HasTexture())
+        {
+        return;
+        }
+
+    TSize space(TInt(aBounds.Width() - aSize.iWidth),
+                TInt(aBounds.Height() - aSize.iHeight));
+
+    TPoint topLeft = aBounds.iTl - AlignOffset(space);
+
+    UpdateColor();
+
+    // Update texture preferred size, toolkit may use this information to resize texture
+    NotifyImagePreferredSize(aImage, THuiRealRect(topLeft,aSize));
+
+    DoDrawImage(aImage, topLeft, aSize);
+    }
+
+
+EXPORT_C void CHuiGc::DrawImages(const THuiImage& aImage,
+                                 const THuiImage& aImage2,
+                                 const THuiRealSize& aSize,
+                                 const THuiRealRect& aBounds)
+    {
+    if(!aImage.HasTexture() || !aImage2.HasTexture())
+        {
+        return;
+        }
+
+    TSize space(TInt(aBounds.Width() - aSize.iWidth),
+                TInt(aBounds.Height() - aSize.iHeight));
+
+    TPoint topLeft = aBounds.iTl - AlignOffset(space);
+
+    UpdateColor();
+
+    // Update texture preferred size, toolkit may use this information to resize texture
+    NotifyImagePreferredSize(aImage, THuiRealRect(topLeft,aSize));
+    NotifyImagePreferredSize(aImage2, THuiRealRect(topLeft,aSize));
+
+    DoDrawImages(aImage, aImage2, topLeft, aSize);
+    }
+
+
+EXPORT_C THuiFont* CHuiGc::Font()
+    {
+    return iCurrentFont;
+    }
+
+
+EXPORT_C TPoint CHuiGc::AlignOffset(const TSize& aBounds) const
+    {
+    TPoint offset(0, 0);
+
+    switch(iAlignHorizontal)
+        {
+        case EHuiAlignHRight:
+            offset.iX = -aBounds.iWidth;
+            break;
+
+        case EHuiAlignHCenter:
+            offset.iX = -aBounds.iWidth / 2;
+            break;
+
+        default:
+            offset.iX = 0;
+            break;
+        }
+
+    switch(iAlignVertical)
+        {
+        case EHuiAlignVBottom:
+            offset.iY = -aBounds.iHeight;
+            break;
+
+        case EHuiAlignVCenter:
+            offset.iY = -aBounds.iHeight / 2;
+            break;
+
+        default:
+            offset.iY = 0;
+            break;
+        }
+
+    return offset;
+    }
+
+
+EXPORT_C TReal32 CHuiGc::Offset2D() const __SOFTFP
+    {
+    /// @todo  Make this configurable.
+    //return 100.0 / FovFactor();
+    return KDefaultOffset2D;
+    }
+
+
+EXPORT_C void
+CHuiGc::SetWindowTransformation(CHuiTransformation* aWindowTransformation)
+    {
+    iWindowTransform = aWindowTransformation;
+    }
+
+
+EXPORT_C TReal32 CHuiGc::NearClipDistance() const __SOFTFP
+    {
+    return iNearClipDistance;
+    }
+
+
+EXPORT_C TReal32 CHuiGc::FarClipDistance() const __SOFTFP
+    {
+    return iFarClipDistance;
+    }
+
+
+EXPORT_C TRect CHuiGc::ProjectionViewport() const
+    {
+    return iProjectionViewport;
+    }
+
+
+EXPORT_C TRect CHuiGc::RawDisplayArea() const
+    {
+    return iDisplayArea;
+    }
+
+
+EXPORT_C const CHuiTransformation* CHuiGc::WindowTransformation() const
+    {
+    return iWindowTransform;
+    }
+
+
+EXPORT_C THuiRealPoint CHuiGc::FrustumOffset() const
+    {
+    return iFrustumOffset;
+    }
+
+
+EXPORT_C TReal32 CHuiGc::FovFactor() const __SOFTFP
+    {
+    return 1.f / iFovFactor;
+    }
+
+
+EXPORT_C THuiAlignHorizontal CHuiGc::LocaleTextAlignment()
+    {
+    if(CHuiStatic::LayoutMirrored())
+        {
+        return EHuiAlignHRight;
+        }
+    return EHuiAlignHLeft;
+    }
+
+EXPORT_C void CHuiGc::DrawStretchImage(TStretchMode /*aMode*/,
+                      const THuiImage& aImage,
+                      const THuiRealRect& aRect,
+                      TInt /*aStretchStartWidth*/,
+                      TInt /*aStretchEndWidth*/)                      
+    {
+    // Update texture preferred size, toolkit may use this information to resize texture
+    NotifyImagePreferredSize(aImage, aRect);        
+    }
+
+
+EXPORT_C void CHuiGc::NotifyImagePreferredSize(const THuiImage& aImage, THuiRealRect aRect)
+    {
+    const CHuiTexture* texture = aImage.ImageDefaultTexture();    
+    
+    if  (texture)
+        {        
+        CHuiTexture* notifiedTexture = const_cast<CHuiTexture*> (texture);
+        if (notifiedTexture->IsAutoSizeCalculationEnabled())
+            {                
+            TReal32 xratio = 1;
+            TReal32 yratio = 1;
+            
+            // Take into account used texture coordinates of THuiImage       
+            TReal32 relativeWidth = aImage.BottomRight().iX - aImage.TopLeft().iX;
+            TReal32 relativeHeight = aImage.BottomRight().iY - aImage.TopLeft().iY;
+            
+            if (relativeWidth != 0.f && relativeHeight != 0.f)
+                {
+                xratio *= (1/relativeWidth);
+                yratio *= (1/relativeHeight);                
+                }
+
+            TReal32 width = aRect.Size().iWidth * xratio;
+            TReal32 height = aRect.Size().iHeight * yratio;
+            
+            // Take into account window transformation scale (To enable HiRes TV-OUT textures)
+            // Other transformations are ignored for now. Possible those could be optionally
+            // taken into account as well if resizing algortihm is lazy enough.
+            CHuiTransformation* wt =  (CHuiTransformation*)WindowTransformation();
+            if (wt)
+                {
+                TInt count = wt->Count();
+                for (TInt i=0;i<count;i++)
+                    {
+                    CHuiTransformation::TTransform& step = wt->Step(i);
+                    if (step.iType == CHuiTransformation::ETypeScale)
+                        {
+                        width = width * step.iParams[EHuiTransformParamTranslateX].Now();    
+                        height = height * step.iParams[EHuiTransformParamTranslateY].Now();    
+                        }                        
+                    }                    
+                }
+            
+            
+            notifiedTexture->NotifyPreferredSize(THuiRealSize(width,height));    
+            }
+        }
+    }
+
+EXPORT_C void CHuiGc::TransformDirtyRect(THuiRealRect& /*aRect*/)
+    {
+    // No sensible implementation for HuiGc base class. Implement at least in
+    // HuiBitgdiGc child class.
+    }
+
+EXPORT_C void CHuiGc::EnableTransformedClippingRects(TBool /*aEnable*/)
+    {
+    // No sensible implementation for HuiGc base class. Implement at least in
+    // HuiBitgdiGc child class.
+    }
+
+EXPORT_C void CHuiGc::SetClip(const TRect& /*aClipRect*/, TBool /*aTransformClipRect*/)
+    {
+    // No sensible implementation for HuiGc base class. Implement at least in
+    // HuiBitgdiGc child class.
+    }
+
+EXPORT_C void CHuiGc::GcExtension(const TUid& /*aExtensionUid*/, TAny** aExtensionParams)
+    {
+    // If no extension with given UID was found, indicate it by returning null
+    *aExtensionParams = NULL;
+    }
+
+RRegion* CHuiGc::CreateRecycledRegion()
+    {
+    RRegion* region = NULL;
+    if (iRecycledRegions.Count())
+        {
+        // If there are recycled regionbufs, use one of those
+        TInt last = iRecycledRegions.Count() - 1;
+        region = iRecycledRegions[last];
+        iRecycledRegions.Remove(last);    
+        }
+    else
+        {
+        // No recycled regionbufs available, create new one
+        region = new RRegionBuf<KHuiGcClipRegionGranularity>();   
+        }    
+    return region;        
+    }
+
+void CHuiGc::DeleteRecycledRegion(RRegion* aRegion)
+    {
+    TInt error = KErrNone;
+    
+    if (iRecycledRegions.Count() < KHuiMaxRecycledRegionCount)
+        {
+        aRegion->Clear();
+        error = iRecycledRegions.Append(aRegion);            
+        if (error)
+            {
+            aRegion->Destroy();
+            }
+        }
+    else
+        {
+        aRegion->Destroy();
+        }                    
+    }