uiacceltk/hitchcock/coretoolkit/src/HuiImageBrush.cpp
changeset 0 15bf7259bb7c
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:   Implements a brush that is able to draw images.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "uiacceltk/HuiImageBrush.h"  // Class definition
       
    21 #include "uiacceltk/HuiDrawing.h"
       
    22 #include "uiacceltk/HuiVisual.h"
       
    23 #include "uiacceltk/HuiUtil.h"
       
    24 
       
    25 
       
    26 EXPORT_C CHuiImageBrush*
       
    27 CHuiImageBrush::NewL(const THuiImage & aImage)
       
    28     {
       
    29     CHuiImageBrush* self = NewLC(aImage);
       
    30     CleanupStack::Pop();
       
    31     return self;
       
    32     }
       
    33 
       
    34 
       
    35 EXPORT_C CHuiImageBrush* CHuiImageBrush::NewLC(const THuiImage & aImage)
       
    36     {
       
    37     CHuiImageBrush* self = new (ELeave) CHuiImageBrush(aImage);
       
    38     CleanupStack::PushL(self);
       
    39     return self;
       
    40     }
       
    41 
       
    42 
       
    43 CHuiImageBrush::CHuiImageBrush(const THuiImage & aImage)
       
    44         : iImage(aImage),
       
    45           iScaleMode(CHuiImageVisual::EScaleFit),
       
    46           iLeftBorderWidth(0),
       
    47           iRightBorderWidth(0),
       
    48 		  iTopBorderWidth(0),
       
    49     	  iBottomBorderWidth(0)
       
    50     	  
       
    51     {
       
    52     SetClipToVisual(EFalse);
       
    53     iScale.Set(1.f);
       
    54     iImageOffset.iX.Set(0.f);
       
    55     iImageOffset.iY.Set(0.f);
       
    56     }
       
    57 
       
    58 EXPORT_C CHuiImageBrush::~CHuiImageBrush()
       
    59     {
       
    60     }
       
    61     
       
    62 EXPORT_C void CHuiImageBrush::SetScaleMode(
       
    63     CHuiImageVisual::TScaleMode aScaleMode)
       
    64     {
       
    65     iScaleMode = aScaleMode;
       
    66     SetChanged();
       
    67     }
       
    68 
       
    69 EXPORT_C void CHuiImageBrush::SetImage(const THuiImage& aImage)
       
    70     {
       
    71     iImage = aImage;
       
    72     SetChanged();
       
    73     }
       
    74 
       
    75 EXPORT_C const THuiImage& CHuiImageBrush::Image() const
       
    76     {
       
    77     return iImage;    
       
    78     }
       
    79 
       
    80 
       
    81 EXPORT_C void CHuiImageBrush::SetBorders(TInt aLeftBorderPixels,
       
    82                          TInt aRightBorderPixels,
       
    83                          TInt aTopBorderPixels,
       
    84                          TInt aBottomBorderPixels)
       
    85 	{
       
    86     iLeftBorderWidth = aLeftBorderPixels;
       
    87     iRightBorderWidth = aRightBorderPixels;
       
    88     iTopBorderWidth = aTopBorderPixels;
       
    89     iBottomBorderWidth = aBottomBorderPixels;
       
    90     SetChanged();
       
    91 	}                         
       
    92 
       
    93 EXPORT_C TBool CHuiImageBrush::BorderDrawingEnabled() const
       
    94 	{
       
    95 	return ((iLeftBorderWidth!=0) || (iRightBorderWidth!=0)		
       
    96 		    || (iTopBorderWidth!=0) || (iBottomBorderWidth!=0));
       
    97 	}
       
    98 
       
    99 EXPORT_C TBool CHuiImageBrush::CenterDrawingEnabled() const
       
   100 	{
       
   101 	if(!iImage.HasTexture()) 
       
   102 		{
       
   103 		return EFalse;
       
   104 		}				
       
   105 	// determine if there are center pixels available inside borders
       
   106 	// if not, we can't draw the center..
       
   107 	TSize imageSize = iImage.Texture().Size();	
       
   108 	if(((imageSize.iWidth - iLeftBorderWidth) - iRightBorderWidth <= 0)
       
   109 	   || ((imageSize.iHeight - iTopBorderWidth) - iBottomBorderWidth <= 0))
       
   110 		{
       
   111 		return EFalse;
       
   112 		}	  
       
   113 		
       
   114 	return ETrue;
       
   115 	}
       
   116 
       
   117 EXPORT_C void CHuiImageBrush::ExpandVisualRect(TRect& aRect) const
       
   118     {
       
   119     if ( CenterDrawingEnabled() )
       
   120         {
       
   121         THuiRealRect contentArea(aRect);
       
   122          
       
   123         // Get the scaled size
       
   124         THuiRealSize imageSize( iImage.Texture().Size() );
       
   125         if ( iScaleMode == CHuiImageVisual::EScaleFit )
       
   126             {
       
   127             imageSize = contentArea.Size() * iScale.Now();
       
   128             }
       
   129         else
       
   130             {
       
   131             TReal32 scale = HuiUtil::CalculateScaleFactorFromScaleMode(
       
   132                 contentArea.Size(),
       
   133                 iImage.Texture().Size(),
       
   134                 iScaleMode,
       
   135                 iScale.Now() );
       
   136             imageSize = imageSize * scale;
       
   137             }
       
   138 
       
   139         THuiRealPoint mid = contentArea.Center();
       
   140         
       
   141         // Move mid point based on the offset
       
   142         TReal32 xOffset = 0;
       
   143         TReal32 yOffset = 0;
       
   144 
       
   145         xOffset = contentArea.Width() * iImageOffset.iX.Now();
       
   146         yOffset = contentArea.Height() * iImageOffset.iY.Now();
       
   147         
       
   148         mid += THuiRealPoint( xOffset, yOffset );
       
   149         
       
   150         // expand the dirty area rect if needed
       
   151         aRect.iTl.iX = Min( aRect.iTl.iX, mid.iX-imageSize.iWidth/2.f );
       
   152         aRect.iTl.iY = Min( aRect.iTl.iY, mid.iY-imageSize.iHeight/2.f );
       
   153         aRect.iBr.iX = Max( aRect.iBr.iX, mid.iX+imageSize.iWidth/2.f );
       
   154         aRect.iBr.iY = Max( aRect.iBr.iY, mid.iY+imageSize.iHeight/2.f );
       
   155         }
       
   156     
       
   157 	if(BorderDrawingEnabled())
       
   158 		{
       
   159         // expand the area of the content to include the border:
       
   160         aRect.Grow((Max(iLeftBorderWidth, 0) + Max(iRightBorderWidth, 0)) / 2, 
       
   161                    (Max(iTopBorderWidth, 0) + Max(iBottomBorderWidth, 0)) / 2);
       
   162         // move the area to justify the border width differencies
       
   163         aRect.Move((Max(iRightBorderWidth, 0)-Max(iLeftBorderWidth, 0)) / 2,
       
   164                    (Max(iTopBorderWidth, 0)-Max(iBottomBorderWidth, 0)) / 2);
       
   165 		}	
       
   166     }
       
   167     
       
   168 TBool CHuiImageBrush::Changed() const
       
   169     {
       
   170     if ( CHuiBrush::Changed() )
       
   171         {
       
   172         return ETrue;
       
   173         }
       
   174     return iImageOffset.Changed() || iScale.Changed() || iImage.Changed();
       
   175     }
       
   176 
       
   177 void CHuiImageBrush::ClearChanged()
       
   178     {
       
   179     CHuiBrush::ClearChanged();
       
   180     iImageOffset.ClearChanged();
       
   181     iScale.ClearChanged();
       
   182     iImage.ClearChanged();
       
   183     }
       
   184 
       
   185 EXPORT_C void CHuiImageBrush::Draw(CHuiGc& aGc, const MHuiBrushGuide& aGuide) const
       
   186     {
       
   187     
       
   188 	TBool borderDrawing = BorderDrawingEnabled();
       
   189 	TBool centerDrawing = CenterDrawingEnabled();
       
   190     
       
   191     TReal32 opacity = aGuide.BrushOpacity() * iOpacity.Now();    
       
   192     aGc.SetPenColor(KRgbWhite);
       
   193     aGc.SetPenAlpha(TInt(opacity * 255.f));
       
   194     
       
   195     if(centerDrawing) 
       
   196 	    {
       
   197         THuiRealRect contentArea = aGuide.BrushRect();
       
   198     
       
   199         aGc.Enable(CHuiGc::EFeatureBlending);
       
   200     
       
   201 	    if(borderDrawing)
       
   202 		    {
       
   203 	        // contract the content area if the borders
       
   204 	        // have been defined to be inside
       
   205 		    if(iLeftBorderWidth < 0)
       
   206 			    {
       
   207 			    contentArea.iTl.iX -= iLeftBorderWidth;
       
   208 			    }
       
   209 		    if(iRightBorderWidth < 0)
       
   210 			    {
       
   211 			    contentArea.iBr.iX += iRightBorderWidth;
       
   212 			    }
       
   213 		    if(iTopBorderWidth < 0)
       
   214 			    {
       
   215 			    contentArea.iTl.iY -= iTopBorderWidth;
       
   216 			    }
       
   217 		    if(iBottomBorderWidth < 0)
       
   218 			    {
       
   219 			    contentArea.iBr.iY += iBottomBorderWidth;
       
   220 			    }
       
   221 		    	
       
   222 		    // Read in the original texture coordinates (NOTE: not affected
       
   223 		    // by any renderer-specific texcoord manipulations, like the Gles POT trick).
       
   224 		    TSize imageSize(iImage.Texture().Size());
       
   225 		    THuiRealPoint tl = iImage.TopLeft(), br = iImage.BottomRight();
       
   226             TReal32 widthU = br.iX - tl.iX;
       
   227             TReal32 heightV = br.iY - tl.iY;
       
   228 
       
   229 			// Remove borders by adjusting texture coordinates.
       
   230 			// But don't divide by 0
       
   231 			if ( imageSize.iWidth != 0 && imageSize.iHeight != 0 )
       
   232 			    {
       
   233     			tl.iX += ((TReal32)Abs(iLeftBorderWidth) / (TReal32)imageSize.iWidth) * widthU;
       
   234     			br.iX -= ((TReal32)Abs(iRightBorderWidth) / (TReal32)imageSize.iWidth) * widthU;
       
   235     			tl.iY += ((TReal32)Abs(iTopBorderWidth) / (TReal32)imageSize.iHeight) * heightV;
       
   236     			br.iY -= ((TReal32)Abs(iBottomBorderWidth) / (TReal32)imageSize.iHeight) * heightV;
       
   237 			    }
       
   238 								    	    		    	    
       
   239 			// Create temporary Image with adjusted texcoords
       
   240 		    THuiImage imageBordersRemoved;
       
   241 		    imageBordersRemoved.SetTexture(iImage.TextureIf());
       
   242 		    imageBordersRemoved.SetTexCoords(tl.iX, tl.iY, br.iX, br.iY);
       
   243 		    
       
   244 		    // Draw the image without the borders.
       
   245 	        aGc.DrawStretchImage(CHuiGc::EStretchFull,
       
   246 	                             imageBordersRemoved,
       
   247 	                             contentArea);		    			
       
   248 		    }
       
   249 	    else
       
   250 		    {	  
       
   251 
       
   252             TReal32 scale = HuiUtil::CalculateScaleFactorFromScaleMode(
       
   253                 contentArea.Size(),
       
   254                 iImage.Texture().Size(),
       
   255                 iScaleMode,
       
   256                 iScale.Now() );
       
   257              
       
   258             // Determine offset.
       
   259             TReal32 xOffset = 0;
       
   260             TReal32 yOffset = 0;
       
   261 
       
   262             xOffset = aGuide.BrushRect().Width() * iImageOffset.iX.Now();
       
   263             yOffset = aGuide.BrushRect().Height() * iImageOffset.iY.Now();
       
   264              
       
   265             
       
   266             // Do scaling
       
   267             TBool doTranslate = !HuiUtil::RealCompare( scale, 1.f ) || !HuiUtil::RealCompare(xOffset,0.f) || !HuiUtil::RealCompare(yOffset,0.f);
       
   268             if( doTranslate )
       
   269                 {
       
   270                 /** @todo  GC must provide some support for transformations. */
       
   271                 aGc.Push(EHuiGcMatrixModel);
       
   272 
       
   273                 // Rotate around the midpoint of the visual.
       
   274                 THuiRealPoint mid = contentArea.Center();
       
   275 
       
   276                 aGc.Translate(EHuiGcMatrixModel, mid.iX + xOffset, mid.iY + yOffset, 0.f);
       
   277                 if( !HuiUtil::RealCompare( scale, 1.f ) )
       
   278                     {
       
   279                     aGc.Scale(EHuiGcMatrixModel, scale, scale, 1.f);
       
   280                     }
       
   281                 aGc.Translate(EHuiGcMatrixModel, -mid.iX, -mid.iY, 0.f);
       
   282                 }
       
   283             
       
   284             // Use the appropriate alignment in the graphics context.
       
   285             if(iScaleMode == CHuiImageVisual::EScaleFit)
       
   286                 {
       
   287                 aGc.SetAlign(EHuiAlignHLeft, EHuiAlignVTop);
       
   288                 }
       
   289             else
       
   290                 {
       
   291                 aGc.SetAlign(EHuiAlignHCenter, EHuiAlignVCenter);
       
   292                 }   
       
   293             
       
   294             // draw the image
       
   295             if(iScaleMode == CHuiImageVisual::EScaleFit)
       
   296                 {
       
   297                 aGc.DrawImage(iImage, contentArea.iTl, contentArea.Size());
       
   298                 }
       
   299             else
       
   300                 {
       
   301                 aGc.DrawImage(iImage, contentArea);
       
   302                 }
       
   303                 
       
   304             // Restore original transformation.
       
   305             if( doTranslate )
       
   306                 {
       
   307                 aGc.Pop(EHuiGcMatrixModel);
       
   308                 }
       
   309         		
       
   310 		    } 
       
   311 
       
   312         }
       
   313 
       
   314 	if(borderDrawing)
       
   315 		{
       
   316         THuiRealRect contentArea = aGuide.BrushRect();
       
   317 		
       
   318         // expand the area of the content to include the border:
       
   319         contentArea.Grow((Max(iLeftBorderWidth, 0) + Max(iRightBorderWidth, 0)) / 2, 
       
   320                    (Max(iTopBorderWidth, 0) + Max(iBottomBorderWidth, 0)) / 2);
       
   321         // move the area to justify the border width differencies
       
   322         contentArea.Move((Max(iRightBorderWidth, 0)-Max(iLeftBorderWidth, 0)) / 2,
       
   323                    (Max(iTopBorderWidth, 0)-Max(iBottomBorderWidth, 0)) / 2);
       
   324                                                           
       
   325 		aGc.DrawBorders(contentArea.Round(),
       
   326 						Abs(iLeftBorderWidth),
       
   327 						Abs(iRightBorderWidth),
       
   328 						Abs(iTopBorderWidth),
       
   329 						Abs(iBottomBorderWidth),
       
   330 						CHuiGc::EBorderFixedCorners,
       
   331 						&iImage);
       
   332 		}
       
   333 
       
   334     }