diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/rendervg10/src/huivg10canvasgc.cpp --- /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 + +#include "huivg10canvasgc.h" +#include "huicanvasgc.h" +#include "HuiVg10Gc.h" +#include "uiacceltk/HuiCanvasVisual.h" +#include "uiacceltk/HuiSkin.h" +#include "uiacceltk/HuiS60Skin.h" +#include +#include "HuiRenderSurface.h" +#include "uiacceltk/HuiDisplay.h" +#include "uiacceltk/HuiEnv.h" +#include "uiacceltk/HuiUtil.h" +#ifndef __SERIES60_30__ +#include "HuiTargetBitmap.h" +#endif + +#include +#include +#include +#include "huiskinbackroundlayout.h" +#include "huivg10canvasrenderbuffer.h" +#include "HuiFxVg10.h" + +CHuiVg10CanvasGc::CHuiVg10CanvasGc() + { + } + +CHuiVg10CanvasGc::~CHuiVg10CanvasGc() + { + } + +void CHuiVg10CanvasGc::DoDrawPolygon(RArray& 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& aItems) + { + if (!iGc) + return; + + THuiDisplayBackgroundItem item; + CHuiS60Skin* s60skin = static_cast(&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& aRects) + { + if(iPolygonDrawMode == EHuiNoFill) + { + CHuiCanvasGc::DoDrawRects(aRects); + } + else + { + for(TInt i=0; i 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); + }