--- /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();
+ }
+ }