uiacceltk/hitchcock/coretoolkit/src/HuiImageBrush.cpp
changeset 0 15bf7259bb7c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiImageBrush.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,334 @@
+/*
+* 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:   Implements a brush that is able to draw images.
+*
+*/
+
+
+
+#include "uiacceltk/HuiImageBrush.h"  // Class definition
+#include "uiacceltk/HuiDrawing.h"
+#include "uiacceltk/HuiVisual.h"
+#include "uiacceltk/HuiUtil.h"
+
+
+EXPORT_C CHuiImageBrush*
+CHuiImageBrush::NewL(const THuiImage & aImage)
+    {
+    CHuiImageBrush* self = NewLC(aImage);
+    CleanupStack::Pop();
+    return self;
+    }
+
+
+EXPORT_C CHuiImageBrush* CHuiImageBrush::NewLC(const THuiImage & aImage)
+    {
+    CHuiImageBrush* self = new (ELeave) CHuiImageBrush(aImage);
+    CleanupStack::PushL(self);
+    return self;
+    }
+
+
+CHuiImageBrush::CHuiImageBrush(const THuiImage & aImage)
+        : iImage(aImage),
+          iScaleMode(CHuiImageVisual::EScaleFit),
+          iLeftBorderWidth(0),
+          iRightBorderWidth(0),
+		  iTopBorderWidth(0),
+    	  iBottomBorderWidth(0)
+    	  
+    {
+    SetClipToVisual(EFalse);
+    iScale.Set(1.f);
+    iImageOffset.iX.Set(0.f);
+    iImageOffset.iY.Set(0.f);
+    }
+
+EXPORT_C CHuiImageBrush::~CHuiImageBrush()
+    {
+    }
+    
+EXPORT_C void CHuiImageBrush::SetScaleMode(
+    CHuiImageVisual::TScaleMode aScaleMode)
+    {
+    iScaleMode = aScaleMode;
+    SetChanged();
+    }
+
+EXPORT_C void CHuiImageBrush::SetImage(const THuiImage& aImage)
+    {
+    iImage = aImage;
+    SetChanged();
+    }
+
+EXPORT_C const THuiImage& CHuiImageBrush::Image() const
+    {
+    return iImage;    
+    }
+
+
+EXPORT_C void CHuiImageBrush::SetBorders(TInt aLeftBorderPixels,
+                         TInt aRightBorderPixels,
+                         TInt aTopBorderPixels,
+                         TInt aBottomBorderPixels)
+	{
+    iLeftBorderWidth = aLeftBorderPixels;
+    iRightBorderWidth = aRightBorderPixels;
+    iTopBorderWidth = aTopBorderPixels;
+    iBottomBorderWidth = aBottomBorderPixels;
+    SetChanged();
+	}                         
+
+EXPORT_C TBool CHuiImageBrush::BorderDrawingEnabled() const
+	{
+	return ((iLeftBorderWidth!=0) || (iRightBorderWidth!=0)		
+		    || (iTopBorderWidth!=0) || (iBottomBorderWidth!=0));
+	}
+
+EXPORT_C TBool CHuiImageBrush::CenterDrawingEnabled() const
+	{
+	if(!iImage.HasTexture()) 
+		{
+		return EFalse;
+		}				
+	// determine if there are center pixels available inside borders
+	// if not, we can't draw the center..
+	TSize imageSize = iImage.Texture().Size();	
+	if(((imageSize.iWidth - iLeftBorderWidth) - iRightBorderWidth <= 0)
+	   || ((imageSize.iHeight - iTopBorderWidth) - iBottomBorderWidth <= 0))
+		{
+		return EFalse;
+		}	  
+		
+	return ETrue;
+	}
+
+EXPORT_C void CHuiImageBrush::ExpandVisualRect(TRect& aRect) const
+    {
+    if ( CenterDrawingEnabled() )
+        {
+        THuiRealRect contentArea(aRect);
+         
+        // Get the scaled size
+        THuiRealSize imageSize( iImage.Texture().Size() );
+        if ( iScaleMode == CHuiImageVisual::EScaleFit )
+            {
+            imageSize = contentArea.Size() * iScale.Now();
+            }
+        else
+            {
+            TReal32 scale = HuiUtil::CalculateScaleFactorFromScaleMode(
+                contentArea.Size(),
+                iImage.Texture().Size(),
+                iScaleMode,
+                iScale.Now() );
+            imageSize = imageSize * scale;
+            }
+
+        THuiRealPoint mid = contentArea.Center();
+        
+        // Move mid point based on the offset
+        TReal32 xOffset = 0;
+        TReal32 yOffset = 0;
+
+        xOffset = contentArea.Width() * iImageOffset.iX.Now();
+        yOffset = contentArea.Height() * iImageOffset.iY.Now();
+        
+        mid += THuiRealPoint( xOffset, yOffset );
+        
+        // expand the dirty area rect if needed
+        aRect.iTl.iX = Min( aRect.iTl.iX, mid.iX-imageSize.iWidth/2.f );
+        aRect.iTl.iY = Min( aRect.iTl.iY, mid.iY-imageSize.iHeight/2.f );
+        aRect.iBr.iX = Max( aRect.iBr.iX, mid.iX+imageSize.iWidth/2.f );
+        aRect.iBr.iY = Max( aRect.iBr.iY, mid.iY+imageSize.iHeight/2.f );
+        }
+    
+	if(BorderDrawingEnabled())
+		{
+        // expand the area of the content to include the border:
+        aRect.Grow((Max(iLeftBorderWidth, 0) + Max(iRightBorderWidth, 0)) / 2, 
+                   (Max(iTopBorderWidth, 0) + Max(iBottomBorderWidth, 0)) / 2);
+        // move the area to justify the border width differencies
+        aRect.Move((Max(iRightBorderWidth, 0)-Max(iLeftBorderWidth, 0)) / 2,
+                   (Max(iTopBorderWidth, 0)-Max(iBottomBorderWidth, 0)) / 2);
+		}	
+    }
+    
+TBool CHuiImageBrush::Changed() const
+    {
+    if ( CHuiBrush::Changed() )
+        {
+        return ETrue;
+        }
+    return iImageOffset.Changed() || iScale.Changed() || iImage.Changed();
+    }
+
+void CHuiImageBrush::ClearChanged()
+    {
+    CHuiBrush::ClearChanged();
+    iImageOffset.ClearChanged();
+    iScale.ClearChanged();
+    iImage.ClearChanged();
+    }
+
+EXPORT_C void CHuiImageBrush::Draw(CHuiGc& aGc, const MHuiBrushGuide& aGuide) const
+    {
+    
+	TBool borderDrawing = BorderDrawingEnabled();
+	TBool centerDrawing = CenterDrawingEnabled();
+    
+    TReal32 opacity = aGuide.BrushOpacity() * iOpacity.Now();    
+    aGc.SetPenColor(KRgbWhite);
+    aGc.SetPenAlpha(TInt(opacity * 255.f));
+    
+    if(centerDrawing) 
+	    {
+        THuiRealRect contentArea = aGuide.BrushRect();
+    
+        aGc.Enable(CHuiGc::EFeatureBlending);
+    
+	    if(borderDrawing)
+		    {
+	        // contract the content area if the borders
+	        // have been defined to be inside
+		    if(iLeftBorderWidth < 0)
+			    {
+			    contentArea.iTl.iX -= iLeftBorderWidth;
+			    }
+		    if(iRightBorderWidth < 0)
+			    {
+			    contentArea.iBr.iX += iRightBorderWidth;
+			    }
+		    if(iTopBorderWidth < 0)
+			    {
+			    contentArea.iTl.iY -= iTopBorderWidth;
+			    }
+		    if(iBottomBorderWidth < 0)
+			    {
+			    contentArea.iBr.iY += iBottomBorderWidth;
+			    }
+		    	
+		    // Read in the original texture coordinates (NOTE: not affected
+		    // by any renderer-specific texcoord manipulations, like the Gles POT trick).
+		    TSize imageSize(iImage.Texture().Size());
+		    THuiRealPoint tl = iImage.TopLeft(), br = iImage.BottomRight();
+            TReal32 widthU = br.iX - tl.iX;
+            TReal32 heightV = br.iY - tl.iY;
+
+			// Remove borders by adjusting texture coordinates.
+			// But don't divide by 0
+			if ( imageSize.iWidth != 0 && imageSize.iHeight != 0 )
+			    {
+    			tl.iX += ((TReal32)Abs(iLeftBorderWidth) / (TReal32)imageSize.iWidth) * widthU;
+    			br.iX -= ((TReal32)Abs(iRightBorderWidth) / (TReal32)imageSize.iWidth) * widthU;
+    			tl.iY += ((TReal32)Abs(iTopBorderWidth) / (TReal32)imageSize.iHeight) * heightV;
+    			br.iY -= ((TReal32)Abs(iBottomBorderWidth) / (TReal32)imageSize.iHeight) * heightV;
+			    }
+								    	    		    	    
+			// Create temporary Image with adjusted texcoords
+		    THuiImage imageBordersRemoved;
+		    imageBordersRemoved.SetTexture(iImage.TextureIf());
+		    imageBordersRemoved.SetTexCoords(tl.iX, tl.iY, br.iX, br.iY);
+		    
+		    // Draw the image without the borders.
+	        aGc.DrawStretchImage(CHuiGc::EStretchFull,
+	                             imageBordersRemoved,
+	                             contentArea);		    			
+		    }
+	    else
+		    {	  
+
+            TReal32 scale = HuiUtil::CalculateScaleFactorFromScaleMode(
+                contentArea.Size(),
+                iImage.Texture().Size(),
+                iScaleMode,
+                iScale.Now() );
+             
+            // Determine offset.
+            TReal32 xOffset = 0;
+            TReal32 yOffset = 0;
+
+            xOffset = aGuide.BrushRect().Width() * iImageOffset.iX.Now();
+            yOffset = aGuide.BrushRect().Height() * iImageOffset.iY.Now();
+             
+            
+            // Do scaling
+            TBool doTranslate = !HuiUtil::RealCompare( scale, 1.f ) || !HuiUtil::RealCompare(xOffset,0.f) || !HuiUtil::RealCompare(yOffset,0.f);
+            if( doTranslate )
+                {
+                /** @todo  GC must provide some support for transformations. */
+                aGc.Push(EHuiGcMatrixModel);
+
+                // Rotate around the midpoint of the visual.
+                THuiRealPoint mid = contentArea.Center();
+
+                aGc.Translate(EHuiGcMatrixModel, mid.iX + xOffset, mid.iY + yOffset, 0.f);
+                if( !HuiUtil::RealCompare( scale, 1.f ) )
+                    {
+                    aGc.Scale(EHuiGcMatrixModel, scale, scale, 1.f);
+                    }
+                aGc.Translate(EHuiGcMatrixModel, -mid.iX, -mid.iY, 0.f);
+                }
+            
+            // Use the appropriate alignment in the graphics context.
+            if(iScaleMode == CHuiImageVisual::EScaleFit)
+                {
+                aGc.SetAlign(EHuiAlignHLeft, EHuiAlignVTop);
+                }
+            else
+                {
+                aGc.SetAlign(EHuiAlignHCenter, EHuiAlignVCenter);
+                }   
+            
+            // draw the image
+            if(iScaleMode == CHuiImageVisual::EScaleFit)
+                {
+                aGc.DrawImage(iImage, contentArea.iTl, contentArea.Size());
+                }
+            else
+                {
+                aGc.DrawImage(iImage, contentArea);
+                }
+                
+            // Restore original transformation.
+            if( doTranslate )
+                {
+                aGc.Pop(EHuiGcMatrixModel);
+                }
+        		
+		    } 
+
+        }
+
+	if(borderDrawing)
+		{
+        THuiRealRect contentArea = aGuide.BrushRect();
+		
+        // expand the area of the content to include the border:
+        contentArea.Grow((Max(iLeftBorderWidth, 0) + Max(iRightBorderWidth, 0)) / 2, 
+                   (Max(iTopBorderWidth, 0) + Max(iBottomBorderWidth, 0)) / 2);
+        // move the area to justify the border width differencies
+        contentArea.Move((Max(iRightBorderWidth, 0)-Max(iLeftBorderWidth, 0)) / 2,
+                   (Max(iTopBorderWidth, 0)-Max(iBottomBorderWidth, 0)) / 2);
+                                                          
+		aGc.DrawBorders(contentArea.Round(),
+						Abs(iLeftBorderWidth),
+						Abs(iRightBorderWidth),
+						Abs(iTopBorderWidth),
+						Abs(iBottomBorderWidth),
+						CHuiGc::EBorderFixedCorners,
+						&iImage);
+		}
+
+    }