--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiImage.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,476 @@
+/*
+* 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 of THuiImage, which specifies an area on
+* a (segmented) texture object.
+*
+*/
+
+
+
+#include "uiacceltk/HuiImage.h" // Class definition
+#include "uiacceltk/HuiTexture.h"
+#include "uiacceltk/HuiUtil.h"
+#include "uiacceltk/HuiPanic.h"
+
+enum THuiImageInternalFlags
+ {
+ EHuiImageFlagDefaultTextureType = 0x1
+ };
+
+
+EXPORT_C THuiImage::THuiImage()
+ : iTexture(0), iTl( 0.f, 0.f ), iBr( 0.f, 0.f )
+ {
+ }
+
+
+EXPORT_C THuiImage::THuiImage(const MHuiTexture& aTexture,
+ TReal32 aTlX, TReal32 aTlY,
+ TReal32 aBrX, TReal32 aBrY) __SOFTFP
+ : iTexture( &aTexture ),
+ iTl( aTlX, aTlY ),
+ iBr( aBrX, aBrY ),
+ iFlags(0)
+ {
+ }
+
+EXPORT_C THuiImage::THuiImage(const CHuiTexture& aTexture,
+ TReal32 aTlX, TReal32 aTlY,
+ TReal32 aBrX, TReal32 aBrY) __SOFTFP
+ : iTexture( &aTexture ),
+ iTl( aTlX, aTlY ),
+ iBr( aBrX, aBrY ),
+ iFlags(EHuiImageFlagDefaultTextureType)
+ {
+ }
+
+
+EXPORT_C TInt THuiImage::SegmentCount() const
+ {
+ if(HasTexture())
+ {
+ return iTexture->SegmentedTexture()->SegmentCount();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+
+EXPORT_C void THuiImage::GetVertexCoords(TInt16* aOutCoords, TInt aSegment) const
+ {
+ if(!iTexture)
+ {
+ for(TInt i = 0; i < 8; ++i)
+ {
+ aOutCoords[i] = 0;
+ }
+ return;
+ }
+
+ const MHuiSegmentedTexture* tex = iTexture->SegmentedTexture();
+ HUI_ASSERT2(tex, THuiPanic::EImageNotSegmentedTexture);
+
+ // Use dummy coordinates, if texture is not available
+ if(SegmentCount() == 0)
+ {
+ for(TInt i = 0; i < 8; ++i)
+ {
+ aOutCoords[i] = 0;
+ }
+ }
+ else
+ {
+ // for handling cases where segmentcount >= 1 ..
+
+ // hmm should we use floating point type here?
+ // anyway here we have TInt to TInt16 conversions..
+ TSize segmentSize = tex->SegmentSize(aSegment);
+ TPoint segmentOffset = tex->SegmentOffset(aSegment);
+ aOutCoords[0] = segmentOffset.iX;
+ aOutCoords[1] = segmentOffset.iY;
+ aOutCoords[2] = segmentOffset.iX + segmentSize.iWidth;
+ aOutCoords[3] = segmentOffset.iY;
+ aOutCoords[4] = aOutCoords[2];
+ aOutCoords[5] = segmentOffset.iY + segmentSize.iHeight;
+ aOutCoords[6] = aOutCoords[0];
+ aOutCoords[7] = aOutCoords[5];
+ }
+ }
+
+
+EXPORT_C void THuiImage::GetTexCoords(TReal32* aTexCoordsOut, TInt aSegment) const
+ {
+ if(!iTexture)
+ {
+ for(TInt i = 0; i < 8; ++i)
+ {
+ aTexCoordsOut[i] = 0;
+ }
+ return;
+ }
+
+ const MHuiSegmentedTexture* tex = iTexture->SegmentedTexture();
+ HUI_ASSERT2(tex, THuiPanic::EImageNotSegmentedTexture);
+
+ // Use dummy coordinates, if texture is not available
+ if(!HasTexture())
+ {
+ for(TInt i = 0; i < 8; ++i)
+ {
+ aTexCoordsOut[i] = 0;
+ }
+ return;
+ }
+
+ if(tex->SegmentCount() == 1)
+ {
+ // user-defined custom coordinates.
+ aTexCoordsOut[0] = iTl.iX.Now();
+ aTexCoordsOut[1] = iTl.iY.Now();
+ aTexCoordsOut[2] = iBr.iX.Now();
+ aTexCoordsOut[3] = iTl.iY.Now();
+ aTexCoordsOut[4] = iBr.iX.Now();
+ aTexCoordsOut[5] = iBr.iY.Now();
+ aTexCoordsOut[6] = iTl.iX.Now();
+ aTexCoordsOut[7] = iBr.iY.Now();
+
+ // NOTE: by default custom coordinates modulate the
+ // coordinates calculated from the textures
+
+ // calculate coordinates based on texture
+ TSize size = tex->SegmentSize(0);
+ TSize textureSize = tex->SegmentTextureSize(0);
+
+ if (textureSize.iWidth)
+ {
+ // if we have partially filled texture ...
+ if (textureSize.iWidth > size.iWidth)
+ {
+ // There has been some visible "ghost lines" and therefore substraction of 0.2 pixels
+ aTexCoordsOut[0] = aTexCoordsOut[0] * (size.iWidth - 0.2f) / textureSize.iWidth;
+ aTexCoordsOut[2] = aTexCoordsOut[2] * (size.iWidth - 0.2f) / textureSize.iWidth;
+ aTexCoordsOut[6] = aTexCoordsOut[0] ;
+ aTexCoordsOut[4] = aTexCoordsOut[2] ;
+
+ }
+ else
+ {
+ // 100% of the texture used,
+ // just use custom coordinates directly
+ }
+ }
+ if(textureSize.iHeight)
+ {
+ // if we have partially filled texture ...
+ if (textureSize.iHeight > size.iHeight)
+ {
+ // There has been some visible "ghost lines" and therefore substraction of 0.2 pixels
+ aTexCoordsOut[3] = aTexCoordsOut[3] * (size.iHeight - 0.2f) / textureSize.iHeight;
+ aTexCoordsOut[1] = aTexCoordsOut[3];
+ aTexCoordsOut[5] = aTexCoordsOut[5] * (size.iHeight - 0.2f) / textureSize.iHeight;
+ aTexCoordsOut[7] = aTexCoordsOut[5];
+ }
+ else
+ {
+ // 100% of the texture used,
+ // just use custom coordinates directly
+ }
+ }
+ }
+ else
+ {
+ // calculate coordinates for multiple segments..
+ TReal32 leftu; // top u coordinate
+ TReal32 rightu; // bottom u coordinate
+ TReal32 topv; // top v coordinate
+ TReal32 bottomv; // bottom v coordinate
+
+ THuiRealSize size = tex->Size();
+ THuiRealSize segmentSize = tex->SegmentSize(aSegment);
+ THuiRealPoint segmentOffset = tex->SegmentOffset(aSegment);
+ // lets do some consistency checks..
+
+ ASSERT(segmentOffset.iX >= 0 && segmentOffset.iX < size.iWidth);
+ ASSERT(segmentOffset.iY >= 0 && segmentOffset.iY < size.iHeight);
+ ASSERT(segmentSize.iWidth > 0 && segmentSize.iWidth <= size.iWidth);
+ ASSERT(segmentSize.iHeight > 0 && segmentSize.iHeight <= size.iHeight);
+ // transform offset and size to texture space
+ segmentOffset.iX /= size.iWidth;
+ segmentOffset.iY /= size.iHeight;
+ segmentSize.iWidth /= size.iWidth;
+ segmentSize.iHeight /= size.iHeight;
+
+ // calculate coordinates
+ // left side..
+ TReal32 edge = iTl.iX.Now();
+ TReal32 offset = segmentOffset.iX;
+ TReal32 width = segmentSize.iWidth;
+ TReal32 coord;
+ if (edge <= offset)
+ {
+ // visible texture edge is at the left/top region (outside),
+ // so this texture segment is fully visible
+ coord = 0.0;
+ }
+ else if (edge - offset < width)
+ {
+ // the edge of the visible texture is somewhere
+ // inside this block, so texture coordinate has
+ // to be set inside
+ coord = (edge - offset)/width;
+ ASSERT(coord>0.0 && coord<1.0);
+ }
+ else
+ {
+ // the edge is outside, at the right/bottom side of this segment.
+ coord = 1.0;
+ }
+ leftu = coord;
+
+ // right side..
+ edge = iBr.iX.Now();
+ if (edge <= offset)
+ {
+ coord = 0.0;
+ }
+ else if (edge - offset < width)
+ {
+ coord = (edge - offset)/width;
+ ASSERT(coord>0.0 && coord<1.0);
+ }
+ else
+ {
+ coord = 1.0;
+ }
+ rightu = coord;
+
+ // top side
+ edge = iTl.iY.Now();
+ offset = segmentOffset.iY;
+ width = segmentSize.iHeight;
+ if (edge <= offset)
+ {
+ coord = 0.0;
+ }
+ else if (edge - offset < width)
+ {
+ coord = (edge - offset)/width;
+ ASSERT(coord>0.0 && coord<1.0);
+ }
+ else
+ {
+ coord = 1.0;
+ }
+ topv = coord;
+
+ // bottom side
+ edge = iBr.iY.Now();
+ if (edge <= offset)
+ {
+ coord = 0.0;
+ }
+ else if (edge - offset < width)
+ {
+ coord = (edge - offset)/width;
+ ASSERT(coord>0.0 && coord<1.0);
+ }
+ else
+ {
+ coord = 1.0;
+ }
+ bottomv = coord;
+
+ // modulate coordinates (if texture utilization != 100%)
+ segmentSize = tex->SegmentSize(aSegment);
+ TSize segmentTexSize = tex->SegmentTextureSize(aSegment);
+ TReal32 uscale = (segmentTexSize.iWidth > 0 ?
+ (TReal32(segmentSize.iWidth) / TReal32(segmentTexSize.iWidth))
+ : 1);
+ TReal32 vscale = (segmentTexSize.iHeight > 0 ?
+ (TReal32(segmentSize.iHeight) / TReal32(segmentTexSize.iHeight))
+ : 1);
+
+ leftu *= uscale;
+ rightu *= uscale;
+ topv *= vscale;
+ bottomv *= vscale;
+
+ // set output coordinates (width)
+ aTexCoordsOut[0] = leftu; // top-left u
+ aTexCoordsOut[2] = rightu; // top-right u
+ aTexCoordsOut[4] = aTexCoordsOut[2]; // bottom-right u
+ aTexCoordsOut[6] = aTexCoordsOut[0]; // bottom-left u
+ // set output coordinates (height)
+ aTexCoordsOut[1] = topv; // top-left v
+ aTexCoordsOut[3] = aTexCoordsOut[1]; // top-right v
+ aTexCoordsOut[5] = bottomv; // bottom-left v
+ aTexCoordsOut[7] = aTexCoordsOut[5]; // bottom-right v
+
+ }
+ }
+
+
+EXPORT_C void THuiImage::SetTexCoords(TReal32 aTlX, TReal32 aTlY,
+ TReal32 aBrX, TReal32 aBrY,
+ TInt aTransitionTime) __SOFTFP
+ {
+ iTl.Set(THuiRealPoint(aTlX, aTlY), aTransitionTime);
+ iBr.Set(THuiRealPoint(aBrX, aBrY), aTransitionTime);
+ }
+
+
+EXPORT_C THuiRealPoint THuiImage::TopLeft() const __SOFTFP
+ {
+ return iTl.RealNow();
+ }
+
+
+EXPORT_C THuiRealPoint THuiImage::BottomRight() const __SOFTFP
+ {
+ return iBr.RealNow();
+ }
+
+
+EXPORT_C void THuiImage::SetTexture(const MHuiTexture& aTexture)
+ {
+ HUI_ASSERT2(aTexture.SegmentedTexture(), THuiPanic::EImageNotSegmentedTexture)
+
+ iTexture = &aTexture;
+
+ // Clear default type flag as we cannot know it for sure
+ iFlags &= ~EHuiImageFlagDefaultTextureType;
+ }
+
+EXPORT_C void THuiImage::SetTexture(const CHuiTexture& aTexture)
+ {
+ iTexture = &aTexture;
+
+ // Set default type flag
+ iFlags |= EHuiImageFlagDefaultTextureType;
+ }
+
+
+EXPORT_C TBool THuiImage::HasTexture() const
+ {
+ return (iTexture && iTexture->SegmentedTexture() && iTexture->HasContent());
+ }
+
+
+EXPORT_C const MHuiTexture& THuiImage::TextureIf() const
+ {
+ HUI_ASSERT2(iTexture != 0, THuiPanic::EImageNoTexture)
+
+ return *iTexture;
+ }
+
+
+EXPORT_C const MHuiSegmentedTexture& THuiImage::Texture() const
+ {
+ HUI_ASSERT2(iTexture != 0, THuiPanic::EImageNoTexture)
+ HUI_ASSERT2(iTexture->SegmentedTexture() != 0, THuiPanic::EImageNotSegmentedTexture)
+
+ return *iTexture->SegmentedTexture();
+ }
+
+
+EXPORT_C TBool THuiImage::HasShadow() const
+ {
+ if(!iTexture || !iTexture->ShadowedTexture())
+ {
+ return EFalse;
+ }
+ return iTexture->ShadowedTexture()->IsShadowEnabled();
+ }
+
+
+EXPORT_C THuiTextureHandle THuiImage::ShadowTexture() const
+ {
+ THuiTextureHandle handle;
+
+ if(iTexture && iTexture->ShadowedTexture())
+ {
+ iTexture->ShadowedTexture()->GetShadowTexture(handle);
+ }
+
+ return handle;
+ }
+
+
+EXPORT_C void THuiImage::Translate(TReal32 aDx, TReal32 aDy, TInt aTransitionTime) __SOFTFP
+ {
+ iTl.iX.Set(iTl.iX.Target() + aDx, aTransitionTime);
+ iTl.iY.Set(iTl.iY.Target() + aDy, aTransitionTime);
+ iBr.iX.Set(iBr.iX.Target() + aDx, aTransitionTime);
+ iBr.iY.Set(iBr.iY.Target() + aDy, aTransitionTime);
+ }
+
+
+EXPORT_C void THuiImage::Scale(TReal32 aScaleX, TReal32 aScaleY, TInt aTransitionTime) __SOFTFP
+ {
+ iTl.iX.Set(iTl.iX.Target() * aScaleX, aTransitionTime);
+ iTl.iY.Set(iTl.iY.Target() * aScaleY, aTransitionTime);
+ iBr.iX.Set(iBr.iX.Target() * aScaleX, aTransitionTime);
+ iBr.iY.Set(iBr.iY.Target() * aScaleY, aTransitionTime);
+ }
+
+
+TBool THuiImage::Changed() const
+ {
+ if(iTexture && iTexture->TextureChanged())
+ {
+ return ETrue;
+ }
+
+ return (iTl.Changed() || iBr.Changed());
+ }
+
+
+void THuiImage::ClearChanged()
+ {
+ if(iTexture)
+ {
+ iTexture->TextureClearChanged();
+ }
+
+ iTl.ClearChanged();
+ iBr.ClearChanged();
+ }
+
+const MHuiTexture* THuiImage::ImageTexture() const
+ {
+ return iTexture;
+ }
+
+const CHuiTexture* THuiImage::ImageDefaultTexture() const
+ {
+ if (iTexture)
+ {
+ // Dynamic cast is slow and this method is called
+ // often, hence the optmization.
+ if (iFlags & EHuiImageFlagDefaultTextureType)
+ {
+ return static_cast<const CHuiTexture*> (iTexture);
+ }
+ else
+ {
+ return dynamic_cast<const CHuiTexture*> (iTexture);
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+ }