uiacceltk/hitchcock/coretoolkit/src/HuiImage.cpp
changeset 0 15bf7259bb7c
child 60 5dafecb0892a
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implementation of THuiImage, which specifies an area on 
       
    15 *                a (segmented) texture object.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include "uiacceltk/HuiImage.h"  // Class definition
       
    22 #include "uiacceltk/HuiTexture.h"
       
    23 #include "uiacceltk/HuiUtil.h"
       
    24 #include "uiacceltk/HuiPanic.h"
       
    25 
       
    26 enum THuiImageInternalFlags
       
    27     {
       
    28     EHuiImageFlagDefaultTextureType = 0x1        
       
    29     };
       
    30 
       
    31 
       
    32 EXPORT_C THuiImage::THuiImage()
       
    33         : iTexture(0), iTl( 0.f, 0.f ), iBr( 0.f, 0.f )
       
    34     {
       
    35     }
       
    36 
       
    37 
       
    38 EXPORT_C THuiImage::THuiImage(const MHuiTexture& aTexture,
       
    39                               TReal32 aTlX, TReal32 aTlY,
       
    40                               TReal32 aBrX, TReal32 aBrY) __SOFTFP
       
    41         : iTexture( &aTexture ),
       
    42           iTl( aTlX, aTlY ), 
       
    43           iBr( aBrX, aBrY ),
       
    44           iFlags(0)
       
    45     {
       
    46     }
       
    47 
       
    48 EXPORT_C THuiImage::THuiImage(const CHuiTexture& aTexture,
       
    49                      TReal32 aTlX, TReal32 aTlY,
       
    50                      TReal32 aBrX, TReal32 aBrY) __SOFTFP
       
    51         : iTexture( &aTexture ),
       
    52           iTl( aTlX, aTlY ), 
       
    53           iBr( aBrX, aBrY ),
       
    54           iFlags(EHuiImageFlagDefaultTextureType)
       
    55     {
       
    56     }
       
    57 
       
    58 
       
    59 EXPORT_C TInt THuiImage::SegmentCount() const
       
    60     {
       
    61     if(HasTexture())
       
    62         {
       
    63         return iTexture->SegmentedTexture()->SegmentCount();
       
    64         }
       
    65     else
       
    66         {
       
    67         return 0;
       
    68         }
       
    69     }
       
    70 
       
    71 
       
    72 EXPORT_C void THuiImage::GetVertexCoords(TInt16* aOutCoords, TInt aSegment) const
       
    73     {
       
    74     if(!iTexture)
       
    75         {
       
    76         for(TInt i = 0; i < 8; ++i)
       
    77             {
       
    78             aOutCoords[i] = 0;
       
    79             }
       
    80         return;
       
    81         }
       
    82     
       
    83     const MHuiSegmentedTexture* tex = iTexture->SegmentedTexture();
       
    84     HUI_ASSERT2(tex, THuiPanic::EImageNotSegmentedTexture);
       
    85     
       
    86     // Use dummy coordinates, if texture is not available
       
    87     if(SegmentCount() == 0)
       
    88         {
       
    89         for(TInt i = 0; i < 8; ++i)
       
    90             {
       
    91             aOutCoords[i] = 0;
       
    92             }
       
    93         }
       
    94     else
       
    95         {
       
    96         // for handling cases where segmentcount >= 1 ..
       
    97 
       
    98         // hmm should we use floating point type here?
       
    99         // anyway here we have TInt to TInt16 conversions..
       
   100         TSize segmentSize = tex->SegmentSize(aSegment);
       
   101         TPoint segmentOffset = tex->SegmentOffset(aSegment);
       
   102         aOutCoords[0] = segmentOffset.iX;
       
   103         aOutCoords[1] = segmentOffset.iY;
       
   104         aOutCoords[2] = segmentOffset.iX + segmentSize.iWidth;
       
   105         aOutCoords[3] = segmentOffset.iY;
       
   106         aOutCoords[4] = aOutCoords[2];
       
   107         aOutCoords[5] = segmentOffset.iY + segmentSize.iHeight;
       
   108         aOutCoords[6] = aOutCoords[0];
       
   109         aOutCoords[7] = aOutCoords[5];
       
   110         }
       
   111     }
       
   112 
       
   113 
       
   114 EXPORT_C void THuiImage::GetTexCoords(TReal32* aTexCoordsOut, TInt aSegment) const
       
   115     {
       
   116     if(!iTexture)
       
   117         {
       
   118         for(TInt i = 0; i < 8; ++i)
       
   119             {
       
   120             aTexCoordsOut[i] = 0;
       
   121             }
       
   122         return;
       
   123         }
       
   124     
       
   125     const MHuiSegmentedTexture* tex = iTexture->SegmentedTexture();
       
   126     HUI_ASSERT2(tex, THuiPanic::EImageNotSegmentedTexture);
       
   127 
       
   128     // Use dummy coordinates, if texture is not available
       
   129     if(!HasTexture())
       
   130         {
       
   131         for(TInt i = 0; i < 8; ++i)
       
   132             {
       
   133             aTexCoordsOut[i] = 0;
       
   134             }
       
   135         return;
       
   136         }
       
   137 
       
   138     if(tex->SegmentCount() == 1)
       
   139         {
       
   140         // user-defined custom coordinates.
       
   141         aTexCoordsOut[0] = iTl.iX.Now();
       
   142         aTexCoordsOut[1] = iTl.iY.Now();
       
   143         aTexCoordsOut[2] = iBr.iX.Now();
       
   144         aTexCoordsOut[3] = iTl.iY.Now();
       
   145         aTexCoordsOut[4] = iBr.iX.Now();
       
   146         aTexCoordsOut[5] = iBr.iY.Now();
       
   147         aTexCoordsOut[6] = iTl.iX.Now();
       
   148         aTexCoordsOut[7] = iBr.iY.Now();
       
   149 
       
   150         // NOTE: by default custom coordinates modulate the
       
   151         // coordinates calculated from the textures
       
   152 
       
   153         // calculate coordinates based on texture
       
   154         TSize size = tex->SegmentSize(0);
       
   155         TSize textureSize = tex->SegmentTextureSize(0);
       
   156 
       
   157         if (textureSize.iWidth)
       
   158             {
       
   159             // if we have partially filled texture ...
       
   160             if (textureSize.iWidth > size.iWidth)
       
   161             	{
       
   162             	// There has been some visible "ghost lines" and therefore substraction of 0.2 pixels
       
   163                 aTexCoordsOut[0] = aTexCoordsOut[0] * (size.iWidth - 0.2f) / textureSize.iWidth;
       
   164                 aTexCoordsOut[2] = aTexCoordsOut[2] * (size.iWidth - 0.2f) / textureSize.iWidth;
       
   165                 aTexCoordsOut[6] = aTexCoordsOut[0] ;
       
   166                 aTexCoordsOut[4] = aTexCoordsOut[2] ;
       
   167 
       
   168                 }
       
   169             else
       
   170                 {
       
   171                 // 100% of the texture used,
       
   172                 // just use custom coordinates directly
       
   173                 }
       
   174             }
       
   175         if(textureSize.iHeight)
       
   176             {
       
   177             // if we have partially filled texture ...
       
   178             if (textureSize.iHeight > size.iHeight)
       
   179                 {
       
   180                 // There has been some visible "ghost lines" and therefore substraction of 0.2 pixels
       
   181                 aTexCoordsOut[3] = aTexCoordsOut[3] * (size.iHeight - 0.2f) / textureSize.iHeight;
       
   182                 aTexCoordsOut[1] = aTexCoordsOut[3];
       
   183                 aTexCoordsOut[5] = aTexCoordsOut[5] * (size.iHeight - 0.2f) / textureSize.iHeight;
       
   184                 aTexCoordsOut[7] = aTexCoordsOut[5];
       
   185                 }
       
   186             else
       
   187                 {
       
   188                 // 100% of the texture used,
       
   189                 // just use custom coordinates directly
       
   190                 }
       
   191             }
       
   192         }
       
   193     else
       
   194         {
       
   195         // calculate coordinates for multiple segments..
       
   196         TReal32 leftu; // top u coordinate
       
   197         TReal32 rightu; // bottom u coordinate
       
   198         TReal32 topv; // top v coordinate
       
   199         TReal32 bottomv; // bottom v coordinate
       
   200 
       
   201         THuiRealSize  size = tex->Size();
       
   202         THuiRealSize  segmentSize = tex->SegmentSize(aSegment);
       
   203         THuiRealPoint segmentOffset = tex->SegmentOffset(aSegment);
       
   204         // lets do some consistency checks..
       
   205 
       
   206         ASSERT(segmentOffset.iX >= 0 && segmentOffset.iX < size.iWidth);
       
   207         ASSERT(segmentOffset.iY >= 0 && segmentOffset.iY < size.iHeight);
       
   208         ASSERT(segmentSize.iWidth > 0 && segmentSize.iWidth <= size.iWidth);
       
   209         ASSERT(segmentSize.iHeight > 0 && segmentSize.iHeight <= size.iHeight);
       
   210         // transform offset and size to texture space
       
   211         segmentOffset.iX /= size.iWidth;
       
   212         segmentOffset.iY /= size.iHeight;
       
   213         segmentSize.iWidth /= size.iWidth;
       
   214         segmentSize.iHeight /= size.iHeight;
       
   215 
       
   216         // calculate coordinates
       
   217         // left side..
       
   218         TReal32 edge = iTl.iX.Now();
       
   219         TReal32 offset = segmentOffset.iX;
       
   220         TReal32 width = segmentSize.iWidth;
       
   221         TReal32 coord;
       
   222         if (edge <= offset)
       
   223             {
       
   224             // visible texture edge is at the left/top region (outside),
       
   225             // so this texture segment is fully visible
       
   226             coord = 0.0;
       
   227             }
       
   228         else if (edge - offset < width)
       
   229             {
       
   230             // the edge of the visible texture is somewhere
       
   231             // inside this block, so texture coordinate has
       
   232             // to be set inside
       
   233             coord = (edge - offset)/width;
       
   234             ASSERT(coord>0.0 && coord<1.0);
       
   235             }
       
   236         else
       
   237             {
       
   238             // the edge is outside, at the right/bottom side of this segment.
       
   239             coord = 1.0;
       
   240             }
       
   241         leftu = coord;
       
   242 
       
   243         // right side..
       
   244         edge = iBr.iX.Now();
       
   245         if (edge <= offset)
       
   246             {
       
   247             coord = 0.0;
       
   248             }
       
   249         else if (edge - offset < width)
       
   250             {
       
   251             coord = (edge - offset)/width;
       
   252             ASSERT(coord>0.0 && coord<1.0);
       
   253             }
       
   254         else
       
   255             {
       
   256             coord = 1.0;
       
   257             }
       
   258         rightu = coord;
       
   259 
       
   260         // top side
       
   261         edge = iTl.iY.Now();
       
   262         offset = segmentOffset.iY;
       
   263         width = segmentSize.iHeight;
       
   264         if (edge <= offset)
       
   265             {
       
   266             coord = 0.0;
       
   267             }
       
   268         else if (edge - offset < width)
       
   269             {
       
   270             coord = (edge - offset)/width;
       
   271             ASSERT(coord>0.0 && coord<1.0);
       
   272             }
       
   273         else
       
   274             {
       
   275             coord = 1.0;
       
   276             }
       
   277         topv = coord;
       
   278 
       
   279         // bottom side
       
   280         edge = iBr.iY.Now();
       
   281         if (edge <= offset)
       
   282             {
       
   283             coord = 0.0;
       
   284             }
       
   285         else if (edge - offset < width)
       
   286             {
       
   287             coord = (edge - offset)/width;
       
   288             ASSERT(coord>0.0 && coord<1.0);
       
   289             }
       
   290         else
       
   291             {
       
   292             coord = 1.0;
       
   293             }
       
   294         bottomv = coord;
       
   295 
       
   296         // modulate coordinates (if texture utilization != 100%)
       
   297         segmentSize = tex->SegmentSize(aSegment);
       
   298         TSize  segmentTexSize = tex->SegmentTextureSize(aSegment);
       
   299         TReal32 uscale = (segmentTexSize.iWidth > 0 ?
       
   300                         (TReal32(segmentSize.iWidth) / TReal32(segmentTexSize.iWidth))
       
   301                         : 1);
       
   302         TReal32 vscale = (segmentTexSize.iHeight > 0 ?
       
   303                         (TReal32(segmentSize.iHeight) / TReal32(segmentTexSize.iHeight))
       
   304                         : 1);
       
   305 
       
   306         leftu *= uscale;
       
   307         rightu *= uscale;
       
   308         topv *= vscale;
       
   309         bottomv *= vscale;
       
   310 
       
   311         // set output coordinates (width)
       
   312         aTexCoordsOut[0] = leftu;    // top-left u
       
   313         aTexCoordsOut[2] = rightu;   // top-right u
       
   314         aTexCoordsOut[4] = aTexCoordsOut[2]; // bottom-right u
       
   315         aTexCoordsOut[6] = aTexCoordsOut[0]; // bottom-left u
       
   316         // set output coordinates (height)
       
   317         aTexCoordsOut[1] = topv; // top-left v
       
   318         aTexCoordsOut[3] = aTexCoordsOut[1]; // top-right v
       
   319         aTexCoordsOut[5] = bottomv; // bottom-left v
       
   320         aTexCoordsOut[7] = aTexCoordsOut[5]; // bottom-right v
       
   321 
       
   322         }
       
   323     }
       
   324 
       
   325 
       
   326 EXPORT_C void THuiImage::SetTexCoords(TReal32 aTlX, TReal32 aTlY,
       
   327                                       TReal32 aBrX, TReal32 aBrY,
       
   328                                       TInt aTransitionTime) __SOFTFP
       
   329     {
       
   330     iTl.Set(THuiRealPoint(aTlX, aTlY), aTransitionTime);
       
   331     iBr.Set(THuiRealPoint(aBrX, aBrY), aTransitionTime);
       
   332     }
       
   333 
       
   334 
       
   335 EXPORT_C THuiRealPoint THuiImage::TopLeft() const __SOFTFP
       
   336     {
       
   337     return iTl.RealNow();
       
   338     }
       
   339 
       
   340 
       
   341 EXPORT_C THuiRealPoint THuiImage::BottomRight() const __SOFTFP
       
   342     {
       
   343     return iBr.RealNow();
       
   344     }
       
   345 
       
   346 
       
   347 EXPORT_C void THuiImage::SetTexture(const MHuiTexture& aTexture)
       
   348     {
       
   349     HUI_ASSERT2(aTexture.SegmentedTexture(), THuiPanic::EImageNotSegmentedTexture)
       
   350         
       
   351     iTexture = &aTexture;
       
   352     
       
   353     // Clear default type flag as we cannot know it for sure
       
   354     iFlags &= ~EHuiImageFlagDefaultTextureType;
       
   355     }
       
   356 
       
   357 EXPORT_C void THuiImage::SetTexture(const CHuiTexture& aTexture)
       
   358     {
       
   359     iTexture = &aTexture;
       
   360 
       
   361     // Set default type flag 
       
   362     iFlags |= EHuiImageFlagDefaultTextureType;
       
   363     }
       
   364 
       
   365 
       
   366 EXPORT_C TBool THuiImage::HasTexture() const
       
   367     {
       
   368     return (iTexture && iTexture->SegmentedTexture() && iTexture->HasContent());
       
   369     }
       
   370 
       
   371 
       
   372 EXPORT_C const MHuiTexture& THuiImage::TextureIf() const
       
   373     {
       
   374     HUI_ASSERT2(iTexture != 0, THuiPanic::EImageNoTexture)
       
   375 
       
   376     return *iTexture;
       
   377     }
       
   378 
       
   379 
       
   380 EXPORT_C const MHuiSegmentedTexture& THuiImage::Texture() const
       
   381     {
       
   382     HUI_ASSERT2(iTexture != 0, THuiPanic::EImageNoTexture)
       
   383     HUI_ASSERT2(iTexture->SegmentedTexture() != 0, THuiPanic::EImageNotSegmentedTexture)
       
   384 
       
   385     return *iTexture->SegmentedTexture();
       
   386     }
       
   387   
       
   388   
       
   389 EXPORT_C TBool THuiImage::HasShadow() const
       
   390     {
       
   391     if(!iTexture || !iTexture->ShadowedTexture())
       
   392         {
       
   393         return EFalse;
       
   394         }
       
   395     return iTexture->ShadowedTexture()->IsShadowEnabled();
       
   396     }
       
   397   
       
   398     
       
   399 EXPORT_C THuiTextureHandle THuiImage::ShadowTexture() const
       
   400     {
       
   401     THuiTextureHandle handle;
       
   402     
       
   403     if(iTexture && iTexture->ShadowedTexture())
       
   404         {
       
   405         iTexture->ShadowedTexture()->GetShadowTexture(handle);
       
   406         }
       
   407         
       
   408     return handle;
       
   409     }    
       
   410 
       
   411 
       
   412 EXPORT_C void THuiImage::Translate(TReal32 aDx, TReal32 aDy, TInt aTransitionTime) __SOFTFP
       
   413     {
       
   414     iTl.iX.Set(iTl.iX.Target() + aDx, aTransitionTime);
       
   415     iTl.iY.Set(iTl.iY.Target() + aDy, aTransitionTime);
       
   416     iBr.iX.Set(iBr.iX.Target() + aDx, aTransitionTime);
       
   417     iBr.iY.Set(iBr.iY.Target() + aDy, aTransitionTime);
       
   418     }
       
   419 
       
   420 
       
   421 EXPORT_C void THuiImage::Scale(TReal32 aScaleX, TReal32 aScaleY, TInt aTransitionTime) __SOFTFP
       
   422     {
       
   423     iTl.iX.Set(iTl.iX.Target() * aScaleX, aTransitionTime);
       
   424     iTl.iY.Set(iTl.iY.Target() * aScaleY, aTransitionTime);
       
   425     iBr.iX.Set(iBr.iX.Target() * aScaleX, aTransitionTime);
       
   426     iBr.iY.Set(iBr.iY.Target() * aScaleY, aTransitionTime);
       
   427     }
       
   428 
       
   429 
       
   430 TBool THuiImage::Changed() const
       
   431 	{
       
   432 	if(iTexture && iTexture->TextureChanged())
       
   433 		{
       
   434 		return ETrue;
       
   435 		}
       
   436 		
       
   437 	return (iTl.Changed() || iBr.Changed());	
       
   438 	}
       
   439 
       
   440 
       
   441 void THuiImage::ClearChanged()
       
   442 	{
       
   443 	if(iTexture)
       
   444 		{
       
   445 		iTexture->TextureClearChanged();
       
   446 		}	
       
   447 		
       
   448     iTl.ClearChanged();
       
   449     iBr.ClearChanged();		
       
   450 	}	    
       
   451 
       
   452 const MHuiTexture* THuiImage::ImageTexture() const
       
   453     {
       
   454     return iTexture;    
       
   455     }
       
   456 
       
   457 const CHuiTexture* THuiImage::ImageDefaultTexture() const
       
   458     {
       
   459     if (iTexture)
       
   460         {            
       
   461         // Dynamic cast is slow and this method is called
       
   462         // often, hence the optmization.        
       
   463         if (iFlags & EHuiImageFlagDefaultTextureType)
       
   464             {
       
   465             return static_cast<const CHuiTexture*> (iTexture);    
       
   466             }
       
   467         else
       
   468             {
       
   469             return dynamic_cast<const CHuiTexture*> (iTexture);                    
       
   470             }    
       
   471         }
       
   472     else
       
   473         {
       
   474         return NULL;    
       
   475         }    
       
   476     }