diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/src/HuiImage.cpp --- /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 (iTexture); + } + else + { + return dynamic_cast (iTexture); + } + } + else + { + return NULL; + } + }