uiacceltk/hitchcock/coretoolkit/rendervg10/src/huivg10canvasgc.cpp
changeset 0 15bf7259bb7c
child 6 10534483575f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/rendervg10/src/huivg10canvasgc.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,334 @@
+/*
+* Copyright (c) 2006-2008 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:   OpenVG class for canvas graphics context
+*
+*/
+
+#include <e32math.h>
+
+#include "huivg10canvasgc.h"
+#include "huicanvasgc.h"
+#include "HuiVg10Gc.h"
+#include "uiacceltk/HuiCanvasVisual.h"
+#include "uiacceltk/HuiSkin.h"
+#include "uiacceltk/HuiS60Skin.h"
+#include <uiacceltk/huidisplaybackgrounditem.h>
+#include "HuiRenderSurface.h"
+#include "uiacceltk/HuiDisplay.h"
+#include "uiacceltk/HuiEnv.h"
+#include "uiacceltk/HuiUtil.h"
+#ifndef __SERIES60_30__     
+#include "HuiTargetBitmap.h"
+#endif
+
+#include <AknsRendererWrapper.h>
+#include <AknsDrawUtils.h>
+#include <coecntrl.h>
+#include "huiskinbackroundlayout.h"
+#include "huivg10canvasrenderbuffer.h"
+#include "HuiFxVg10.h"
+
+CHuiVg10CanvasGc::CHuiVg10CanvasGc()
+    {
+    }
+
+CHuiVg10CanvasGc::~CHuiVg10CanvasGc()
+    {	
+    }
+
+void CHuiVg10CanvasGc::DoDrawPolygon(RArray<THuiRealPoint>& aPoints)
+    {
+    if(iPolygonDrawMode == EHuiNoFill)
+    	{
+    	CHuiCanvasGc::DoDrawPolygon(aPoints);
+    	}
+    else
+        {
+        CHuiVg10Gc* vg10Gc = (CHuiVg10Gc *)iGc;
+        vg10Gc->SetFillRule( iPolygonDrawMode );
+        vg10Gc->SetPaintPattern(iPolygonFillTexture, iPolygonFillTextureOrigin);
+        vg10Gc->DrawPolygon(aPoints);                
+        vg10Gc->SetPaintPattern(NULL, iPolygonFillTextureOrigin);
+        }	    
+    }
+
+void CHuiVg10CanvasGc::DoDrawArc(const THuiRealRect& aDestinationRect, 
+       const THuiRealPoint& aStart, const THuiRealPoint& aEnd) 
+   {
+   DoDrawPieAndArc( aDestinationRect, aStart, aEnd, EFalse);
+   }
+   
+void CHuiVg10CanvasGc::DoDrawPie(const THuiRealRect& aDestinationRect, 
+        const THuiRealPoint& aStart, const THuiRealPoint& aEnd)
+    {
+    DoDrawPieAndArc( aDestinationRect, aStart, aEnd, ETrue);
+    }
+
+
+void CHuiVg10CanvasGc::DoDrawPieAndArc(const THuiRealRect& aDestinationRect, 
+      const THuiRealPoint& aStart, const THuiRealPoint& aEnd, TBool aIsPie)  
+    {    
+    THuiRealRect destinationRect = aDestinationRect;
+    destinationRect.Shrink(0.5f, 0.5f);    
+    THuiRealPoint center = destinationRect.Center();
+
+    // Ok, explaining this is not going to be easy. So, please pay attention!
+    //
+    // Symbian Window Gc DrawArc() method always draws an arc anti-clockwise, from start angle
+    // to end angle. As y-axis in Window GC point downwards, the angle grows towards *negative*
+    // direction, if we go anti-clockwise. To be able to make calculations later we have to make 
+    // sure both the start and end angles are negative.
+    // 
+    TReal startAngle = 0;
+    Math::ATan(startAngle, aStart.iY - center.iY,  aStart.iX - center.iX);
+    startAngle = (startAngle*180)/KPi;   
+    // make sure this is negative angle
+    if (startAngle > - 0.000001) 
+        {
+        startAngle -= 360.0; 
+        }
+        
+    TReal endAngle = 0;
+    Math::ATan(endAngle, aEnd.iY - center.iY, aEnd.iX - center.iX);
+    endAngle = (endAngle*180)/KPi;   
+    // make sure this is negative angle
+    if (endAngle > - 0.000001) 
+        {
+        endAngle -= 360.0; 
+        }
+
+    // Make a full circle if the end and start angles are equal
+    if ( Abs(endAngle-startAngle) < 0.000001)
+        {
+        endAngle -= 360.0;
+        }
+
+    // Organize angles so that we go from start to end angle anti-clockwise, i.e. towards negative direction
+    if ( endAngle > startAngle )
+        {
+        endAngle -= 360;
+        }
+
+    CHuiVg10Gc* vg10Gc = (CHuiVg10Gc *)iGc;
+    vg10Gc->SetPaintPattern(iPolygonFillTexture, iPolygonFillTextureOrigin);
+    vg10Gc->DrawArc(aDestinationRect.Round(), iPolygonDrawMode, iPenWidth, startAngle, endAngle, aIsPie);
+    vg10Gc->SetPaintPattern(NULL, iPolygonFillTextureOrigin);  
+    }
+
+ void CHuiVg10CanvasGc::DoDrawRoundRect(const THuiRealRect& aDestinationRect, const THuiRealSize& aSize)
+     {
+     CHuiVg10Gc* vg10Gc = (CHuiVg10Gc *)iGc;
+     vg10Gc->SetPaintPattern(iPolygonFillTexture, iPolygonFillTextureOrigin);
+     vg10Gc->DrawRoundRect(aDestinationRect.Round(), aSize, iPolygonDrawMode, iPenWidth);
+     vg10Gc->SetPaintPattern(NULL, iPolygonFillTextureOrigin);
+     }
+ 
+void CHuiVg10CanvasGc::ClearWithSkinBackground(const THuiRealRect& /*aRect*/) 
+    {
+    if (!iGc)
+        {
+        return;    
+        }
+
+    // Acquire background texture
+    const CHuiTexture* backgroundTexture = NULL;
+    TInt err = CHuiStatic::Env().Skin().GetTexture(EHuiSkinBackgroundTexture, backgroundTexture);
+    ASSERT(backgroundTexture!=NULL);
+    __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
+
+    // Apply background texture
+    THuiImage background(*backgroundTexture);
+
+    TPoint screenOrigin(0, 0);
+    CHuiStatic::CurrentRenderSurface()->GetScreenOrigin(screenOrigin);
+    // The origin is used to offset the background in the display's
+    // rendering surface, so that the background's origin is in the
+    // top left screen corner.
+    screenOrigin.iX = -screenOrigin.iX;
+    screenOrigin.iY = -screenOrigin.iY;
+
+    iGc->SetPenColor(KRgbWhite);
+    iGc->SetPenAlpha(255);
+    iGc->SetAlign(EHuiAlignHLeft, EHuiAlignVTop);            
+    iGc->Disable(CHuiGc::EFeatureBlending);
+    iGc->Disable(CHuiGc::EFeatureClipping);            
+    iGc->DrawImage(background, screenOrigin, background.Texture().Size()); 
+    iGc->Enable(CHuiGc::EFeatureBlending);
+    iGc->Enable(CHuiGc::EFeatureClipping);            
+    }
+
+void CHuiVg10CanvasGc::ClearWithBackgroundItems(const THuiRealRect& /*aRect*/, const RArray<THuiDisplayBackgroundItem>& aItems)
+    {
+    if (!iGc)
+        return;
+
+    THuiDisplayBackgroundItem item;   
+    CHuiS60Skin* s60skin = static_cast<CHuiS60Skin*>(&CHuiStatic::Env().Skin());
+    CHuiTexture* backgroundTexture = NULL;
+
+    for (TInt index = 0; index < aItems.Count(); index++)
+        {        
+        item = aItems[index];    
+        switch (item.ClearMode())
+            {
+            case CHuiDisplay::EClearNone:
+                // do nothing...
+                break;
+            case CHuiDisplay::EClearWithColor:
+                iGc->SetPenColor(item.Color());
+                iGc->SetPenAlpha(TInt(item.Color().Alpha() * 255));
+                iGc->SetAlign(EHuiAlignHLeft, EHuiAlignVTop);            
+                iGc->Disable(CHuiGc::EFeatureBlending);
+                iGc->Enable(CHuiGc::EFeatureClipping);            
+                iGc->PushClip();
+                iGc->Clip(item.Rect());  // takes transformations into account                              
+                iGc->Clear();
+                iGc->PopClip();
+                break;
+            case CHuiDisplay::EClearWithSkinBackground:
+                 TRect skinRect;
+                 TRect dummy;
+                 GetRectForItem(item.SkinBackground(), dummy, skinRect);
+                 backgroundTexture = s60skin->BackgroundTexture(item.SkinBackground());
+                 if (backgroundTexture)
+                    {
+                    THuiImage background(*backgroundTexture);
+
+                    TPoint screenOrigin(0, 0);
+                    CHuiStatic::CurrentRenderSurface()->GetScreenOrigin(screenOrigin);
+                    screenOrigin.iX = -screenOrigin.iX;
+                    screenOrigin.iY = -screenOrigin.iY;
+                    screenOrigin+=skinRect.iTl;
+                    iGc->SetPenColor(KRgbWhite);
+                    iGc->SetPenAlpha(255);
+                    iGc->SetAlign(EHuiAlignHLeft, EHuiAlignVTop);            
+                    iGc->Disable(CHuiGc::EFeatureBlending);
+                    iGc->Enable(CHuiGc::EFeatureClipping);            
+                    skinRect.Intersection(item.Rect());
+                    iGc->PushClip();
+                    iGc->Clip(skinRect); // takes transformations into account
+                    iGc->DrawImage(background, screenOrigin, background.Texture().Size());                     
+                    iGc->PopClip();
+                    }
+                 break;                                                    
+             }
+        }             
+    }
+
+TInt CHuiVg10CanvasGc::MaxNumberOfClipRects() const
+    {
+    // We could ask this number from OpenVg, but spec says that at least 32 must be supported
+    return 32;    
+    }
+
+CHuiCanvasRenderBuffer* CHuiVg10CanvasGc::CreateRenderBufferL(const TSize& /*aSize*/)
+    {
+    CHuiVg10CanvasRenderBuffer* buffer = new (ELeave) CHuiVg10CanvasRenderBuffer;
+    return buffer;
+    }
+
+void CHuiVg10CanvasGc::DoDrawRenderBuffer(const CHuiCanvasRenderBuffer& aImage, const THuiRealPoint& aDestinationPoint)
+    {
+    const CHuiVg10CanvasRenderBuffer* vg10RenderBuffer = (const CHuiVg10CanvasRenderBuffer*) &aImage;    
+    
+    CHuiVg10Gc* vg10Gc = (CHuiVg10Gc *)iGc;
+    if (vg10RenderBuffer->Image())
+        {
+        vg10Gc->UpdateColor();
+        iGc->Push(EHuiGcMatrixModel);
+        vgTranslate(aDestinationPoint.iX, aDestinationPoint.iY);
+        vgDrawImage(vg10RenderBuffer->Image());
+        iGc->Pop(EHuiGcMatrixModel);
+        }
+    }
+
+void CHuiVg10CanvasGc::DoClearRenderBuffer( CHuiCanvasRenderBuffer& aImage, const TRect & aRect )
+    {
+    HUIFX_VG_INVARIANT();   
+    const CHuiVg10CanvasRenderBuffer* vg10RenderBuffer = (const CHuiVg10CanvasRenderBuffer*) &aImage;    
+
+    const TInt COLOR_COMPONENTS = 4;
+    VGfloat savedColor[COLOR_COMPONENTS];
+    vgGetfv(VG_CLEAR_COLOR, COLOR_COMPONENTS, savedColor);
+    
+    VGfloat color[COLOR_COMPONENTS] = 
+                {
+                 0.0f, 0.0f, 0.0f, 0.0f
+                };
+    vgSetfv(VG_CLEAR_COLOR, COLOR_COMPONENTS, color);
+    vgClearImage(vg10RenderBuffer->Image(), aRect.iTl.iX, aRect.iTl.iY, aRect.Size().iWidth, aRect.Size().iHeight);
+    vgSetfv(VG_CLEAR_COLOR, COLOR_COMPONENTS, savedColor);
+    HUIFX_VG_INVARIANT();   
+    }
+
+
+void CHuiVg10CanvasGc::RestoreFlaggedState() const
+    {
+    if (iGc)
+        {
+        CHuiVg10Gc* vg10Gc = (CHuiVg10Gc *)iGc;
+        vg10Gc->RestoreFlaggedState();
+        }
+    }
+
+void CHuiVg10CanvasGc::DoDrawRects(RArray<THuiRealRect>& aRects)
+    {
+    if(iPolygonDrawMode == EHuiNoFill)
+        {
+        CHuiCanvasGc::DoDrawRects(aRects);
+        }
+    else
+        {
+        for(TInt i=0; i<aRects.Count(); i++)
+            {
+            TRect roundedRect = aRects[i].Round();
+            if (roundedRect.Height() > 0 && roundedRect.Width() > 0)
+                {                   
+                CHuiVg10Gc* vg10Gc = (CHuiVg10Gc *)iGc;
+                vg10Gc->SetPaintPattern(iPolygonFillTexture, iPolygonFillTextureOrigin);
+                iGc->DrawRect(roundedRect);
+                vg10Gc->SetPaintPattern(NULL, iPolygonFillTextureOrigin);
+                }           
+            }            
+        }
+    }
+
+void CHuiVg10CanvasGc::DrawEllipse(const THuiRealRect& aDestinationRect)
+    {   
+    if (!iGc)
+       {
+       return;    
+       }
+
+    Setup();
+
+    EnableDelayedClippingIfNeeded(aDestinationRect);    
+
+    while (ClipNext())
+        {
+        DoDrawEllipse( aDestinationRect );
+        }
+
+    DisableDelayedClippingIfNeeded();    
+
+    Cleanup();
+    }
+
+void CHuiVg10CanvasGc::DoDrawEllipse(const THuiRealRect& aDestinationRect)
+    {   
+    CHuiVg10Gc* vg10Gc = (CHuiVg10Gc *)iGc;
+    vg10Gc->SetPaintPattern(iPolygonFillTexture, iPolygonFillTextureOrigin);
+    vg10Gc->DrawEllipse(aDestinationRect.Round(), iPolygonDrawMode, iPenWidth);
+    vg10Gc->SetPaintPattern(NULL, iPolygonFillTextureOrigin);                
+    }