uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10Gc.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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 CHuiVg10Gc, an OpenVG 1.0 version of the HUITK
       
    15 *                graphics context.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include "HuiVg10Gc.h"  // Class definition
       
    22 #include "HuiVg10RenderPlugin.h"
       
    23 #include "HuiVg10Texture.h"
       
    24 #include "HuiVg10RenderSurface.h"
       
    25 #include "uiacceltk/HuiSegmentedTexture.h"
       
    26 #include "uiacceltk/HuiFont.h"
       
    27 #include "uiacceltk/HuiImage.h"
       
    28 #include "uiacceltk/HuiTextMesh.h"
       
    29 #include "uiacceltk/HuiCurvePath.h"
       
    30 #include "uiacceltk/HuiTransformation.h"
       
    31 #include "uiacceltk/HuiUtil.h"
       
    32 #include "uiacceltk/HuiPanic.h"
       
    33 #include "uiacceltk/huifixmath.h"
       
    34 #include "HuiRenderSurface.h"
       
    35 #include "../../CommonInc/uiacceltkdomaincrkeys.h"
       
    36 
       
    37 #include <e32math.h>
       
    38 #include <VG/vgu.h>
       
    39 #ifdef __NVG
       
    40 #pragma message( "NVG Defined!" )
       
    41     #include <nvg.h>
       
    42     #include <AknIconHeader.h>
       
    43     #include <AknIconUtils.h>
       
    44     #include "NVGIcon.h"
       
    45 #endif
       
    46 
       
    47 const TInt KHuiMaxVgScissorRects = 32;
       
    48 
       
    49 /** Only render colorful rectangles instead of real graphics 
       
    50  *  content. Useful for debugging broken OpenVG drivers.
       
    51  */
       
    52 //#define RENDER_DEBUG_RECTANGLES
       
    53 
       
    54 CHuiVg10Gc* CHuiVg10Gc::NewL()
       
    55     {
       
    56     CHuiVg10Gc* self = CHuiVg10Gc::NewLC();
       
    57     CleanupStack::Pop(self);
       
    58     return self;
       
    59     }
       
    60 
       
    61 
       
    62 CHuiVg10Gc* CHuiVg10Gc::NewLC()
       
    63     {
       
    64     CHuiVg10Gc* self = new (ELeave) CHuiVg10Gc();
       
    65     CleanupStack::PushL(self);
       
    66     self->ConstructL();
       
    67     return self;
       
    68     }
       
    69 
       
    70 
       
    71 CHuiVg10Gc::CHuiVg10Gc()
       
    72         : CHuiGc()
       
    73     {
       
    74     }
       
    75 
       
    76 
       
    77 void CHuiVg10Gc::ConstructL()
       
    78     {
       
    79     // iMatrix stack must be allocated here because InitState() is not allowed to leave
       
    80     
       
    81     iMatrixStack = CHuiMatrixStack::NewL();
       
    82 #ifdef __NVG
       
    83     CHuiVg10RenderPlugin& renderer = (CHuiVg10RenderPlugin&) CHuiStatic::Renderer();
       
    84     iNvgEngine = &renderer.NvgEngine();
       
    85 #endif    
       
    86     }
       
    87 
       
    88 
       
    89 CHuiVg10Gc::~CHuiVg10Gc()
       
    90     {
       
    91 #ifdef __NVG
       
    92     // Don't delete the iNvgEngine, it's owned by the plugin!
       
    93     iNvgEngine = NULL;
       
    94 #endif    
       
    95     delete iMatrixStack;
       
    96     
       
    97     vgDestroyPath(iPath);
       
    98     vgDestroyPath(iImagePath);
       
    99     vgDestroyPath(iRectPath);
       
   100     vgDestroyPath(iRoundRectPath);
       
   101     vgDestroyPath(iLinePath);
       
   102     vgDestroyPath(iBorderPath);
       
   103     vgDestroyPath(iArcPath);
       
   104     vgDestroyPaint(iPaint);
       
   105     vgDestroyPaint(iGradientPaint);
       
   106     vgDestroyPath(iEllipsePath);
       
   107     }
       
   108     
       
   109 
       
   110 void CHuiVg10Gc::Push(THuiGcMatrix aMatrix)
       
   111     {
       
   112     if (aMatrix == EHuiGcMatrixModel)
       
   113         {
       
   114         // Replicate the current OpenVG matrix to the matrix stack
       
   115         UpdateClientMatrix();
       
   116         iMatrixStack->Push();
       
   117         
       
   118         // Save the matrix flags
       
   119         iMatrixFlagsStack.Append(iMatrixFlags);
       
   120         }
       
   121     }
       
   122 
       
   123 
       
   124 void CHuiVg10Gc::Pop(THuiGcMatrix aMatrix)
       
   125     {
       
   126     if (aMatrix == EHuiGcMatrixModel)
       
   127         {
       
   128         // Replicate the current matrix to OpenVG
       
   129         iMatrixStack->Pop();
       
   130         CHuiMatrixStack::TMatrix& matrix = iMatrixStack->Current();
       
   131         vgLoadMatrix((VGfloat*)matrix.iMatrix);
       
   132         
       
   133         // Restore the matrix flags
       
   134         iMatrixFlags = iMatrixFlagsStack[iMatrixFlagsStack.Count() - 1];
       
   135         iMatrixFlagsStack.Remove(iMatrixFlagsStack.Count() - 1);
       
   136         HUI_VG_INVARIANT();
       
   137         }
       
   138     }
       
   139 
       
   140 
       
   141 void CHuiVg10Gc::LoadIdentity(THuiGcMatrix aMatrix)
       
   142     {
       
   143     if (aMatrix == EHuiGcMatrixModel)
       
   144         {
       
   145         vgLoadIdentity();
       
   146         
       
   147         TRect displayArea = DisplayArea();            
       
   148         TInt h = displayArea.Height();
       
   149         TInt w = displayArea.Width();
       
   150 
       
   151         // DisplayArea is rotated if orientation is rotated, so we must "counter rotate"
       
   152         // to avoid rotating too much.
       
   153         if(Orientation() == EOrientationCCW90 || Orientation() == EOrientationCW90)
       
   154             {
       
   155             TInt tmp = w;
       
   156             w = h;
       
   157             h = tmp;
       
   158             }
       
   159         
       
   160         // Flip the Y axis to match Hitchcock's coordinate system
       
   161         vgTranslate(0, h); 
       
   162         vgScale(1.0f, -1.0f);
       
   163         
       
   164         if(Orientation() == EOrientationCCW90)
       
   165             {
       
   166             // Rotate around origo and move back to displayarea
       
   167             vgRotate(90);
       
   168             vgTranslate(0, -w);
       
   169             }
       
   170         else if(Orientation() == EOrientationCW90)
       
   171             {            
       
   172             // Rotate around origo and move back to displayarea
       
   173             vgRotate(-90);
       
   174             vgTranslate(-h, 0);
       
   175             }
       
   176         else if (Orientation() == EOrientation180)
       
   177             {
       
   178             // Rotate around origo and move back to displayarea
       
   179             vgRotate(-180);
       
   180             vgTranslate(-w, -h);            
       
   181             }                   
       
   182         else
       
   183             {
       
   184             // Nothing to do ?
       
   185             }
       
   186         
       
   187         // Reset the flags for this matrix
       
   188         iMatrixFlags = 0;
       
   189         
       
   190         HUI_VG_INVARIANT();
       
   191         }
       
   192     }
       
   193 
       
   194 
       
   195 void CHuiVg10Gc::Multiply(THuiGcMatrix aStack, TReal32 aMatrix[16])
       
   196     {
       
   197     if (aStack == EHuiGcMatrixModel)
       
   198         {
       
   199         const VGfloat m[9] = 
       
   200             {
       
   201             aMatrix[0], aMatrix[1], aMatrix[2],
       
   202             aMatrix[4], aMatrix[5], aMatrix[6],
       
   203             aMatrix[8], aMatrix[9], aMatrix[10],
       
   204             };
       
   205         vgMultMatrix(m);
       
   206         HUI_VG_INVARIANT();
       
   207         }
       
   208     }
       
   209 
       
   210 
       
   211 void CHuiVg10Gc::Translate(THuiGcMatrix aMatrix,
       
   212                            TReal32 aX, TReal32 aY, TReal32 /*aZ*/) __SOFTFP
       
   213     {
       
   214     if (aMatrix == EHuiGcMatrixModel)
       
   215         {
       
   216         vgTranslate(aX, aY);
       
   217         HUI_VG_INVARIANT();
       
   218         }
       
   219     }
       
   220 
       
   221 
       
   222 void CHuiVg10Gc::Scale(THuiGcMatrix aMatrix,
       
   223                          TReal32 aX, TReal32 aY, TReal32 /*aZ*/) __SOFTFP
       
   224     {
       
   225     if (aMatrix == EHuiGcMatrixModel)
       
   226         {
       
   227         vgScale(aX, aY);
       
   228         HUI_VG_INVARIANT();
       
   229         }
       
   230     }
       
   231 
       
   232 void CHuiVg10Gc::Shear(THuiGcMatrix aMatrix,
       
   233                        TReal32 aX, TReal32 aY, TReal32 /*aZ*/) __SOFTFP
       
   234     {
       
   235     if (aMatrix == EHuiGcMatrixModel)
       
   236         {
       
   237         vgShear(aX, aY);
       
   238         HUI_VG_INVARIANT();
       
   239         }
       
   240     }
       
   241 
       
   242 void CHuiVg10Gc::Rotate(THuiGcMatrix aMatrix, TReal32 aAngle,
       
   243                         TReal32 aX, TReal32 aY, TReal32 aZ) __SOFTFP
       
   244     {
       
   245     if (aMatrix != EHuiGcMatrixModel)
       
   246         {
       
   247         return;
       
   248         }
       
   249 
       
   250     // Only rotation around the unit Z axis is supported
       
   251 	if (aX != 0.0f || aY != 0.0f || Abs(aZ) != 1.0f)
       
   252 	    {
       
   253 	    return;
       
   254 	    }
       
   255 		
       
   256     if (aZ < 0)
       
   257         {
       
   258         aAngle = -aAngle;
       
   259         }
       
   260     
       
   261     iMatrixFlags |= EMatrixFlagsRotation;
       
   262     vgRotate(aAngle);
       
   263     HUI_VG_INVARIANT();
       
   264     }
       
   265 
       
   266 
       
   267 // Replicate the current OpenVG matrix to the matrix stack
       
   268 void CHuiVg10Gc::UpdateMatrix(VGMatrixMode aMatrix)
       
   269     {
       
   270     VGfloat m[9];
       
   271     ASSERT(vgGeti(VG_MATRIX_MODE) == VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
   272     vgGetMatrix(m);
       
   273     vgSeti(VG_MATRIX_MODE, aMatrix);
       
   274     vgLoadMatrix(m);
       
   275     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
   276         
       
   277     HUI_VG_INVARIANT();
       
   278     }
       
   279 
       
   280 void CHuiVg10Gc::UpdateClientMatrix()
       
   281     {
       
   282     // Replicate the current OpenVG matrix to the matrix stack
       
   283     vgGetMatrix((VGfloat*)iMatrixStack->Current().iMatrix);
       
   284     
       
   285     // The matrix is *probably* not an identity transform
       
   286     iMatrixStack->Current().iIsIdentity = EFalse;
       
   287     HUI_VG_INVARIANT();
       
   288     }
       
   289 
       
   290 void CHuiVg10Gc::CreateVgObjectsL()
       
   291     {
       
   292     // Make sure we have enough resources to work with
       
   293     ASSERT(vgGeti(VG_MAX_SCISSOR_RECTS) >= 1);
       
   294     
       
   295     // Create the default VG objects
       
   296     iPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   297                          5, 8, VG_PATH_CAPABILITY_APPEND_TO);
       
   298     iImagePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   299                               5, 8, VG_PATH_CAPABILITY_APPEND_TO | VG_PATH_CAPABILITY_MODIFY);
       
   300     iArcPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   301                             2, 7, VG_PATH_CAPABILITY_APPEND_TO);
       
   302     iPaint = vgCreatePaint();
       
   303     iGradientPaint = vgCreatePaint();
       
   304     iBlendMode = VG_BLEND_SRC_OVER;
       
   305 
       
   306     // Initialize a rectangle path with dummy coordinates
       
   307     iRectPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   308                              5, 8, VG_PATH_CAPABILITY_APPEND_TO | VG_PATH_CAPABILITY_MODIFY);
       
   309 
       
   310     iRoundRectPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   311                                  5, 8, VG_PATH_CAPABILITY_APPEND_TO | VG_PATH_CAPABILITY_MODIFY);
       
   312 
       
   313     iEllipsePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   314                                  5, 8, VG_PATH_CAPABILITY_APPEND_TO | VG_PATH_CAPABILITY_MODIFY);
       
   315     
       
   316     const VGubyte rectSegments[] =
       
   317         {
       
   318         VG_MOVE_TO_ABS,
       
   319         VG_LINE_TO_REL,
       
   320         VG_LINE_TO_REL,
       
   321         VG_LINE_TO_REL,
       
   322         VG_CLOSE_PATH
       
   323         };
       
   324     const VGfloat rectCoords[] = 
       
   325         {
       
   326          0.0f, 0.0f,             // (x, y)
       
   327          1.0f, 0.0f,             // (width, 0)
       
   328          0.0f, 1.0f,             // (0, height)
       
   329         -1.0f, 0.0f,             // (-width, 0)
       
   330         };
       
   331     vgAppendPathData(iRectPath, 5, rectSegments, rectCoords);
       
   332     vgRemovePathCapabilities(iRectPath, VG_PATH_CAPABILITY_APPEND_TO);
       
   333     vgAppendPathData(iImagePath, 5, rectSegments, rectCoords);
       
   334     vgRemovePathCapabilities(iImagePath, VG_PATH_CAPABILITY_APPEND_TO);
       
   335 
       
   336     // Initialize a line path with dummy coordinates
       
   337     iLinePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   338                              2, 4, VG_PATH_CAPABILITY_APPEND_TO | VG_PATH_CAPABILITY_MODIFY);
       
   339     const VGubyte lineSegments[] =
       
   340         {
       
   341         VG_MOVE_TO_ABS,
       
   342         VG_LINE_TO_ABS,
       
   343         };
       
   344     const VGfloat lineCoords[] = 
       
   345         {
       
   346         0.0f, 0.0f,             // (x, y)
       
   347         1.0f, 1.0f,             // (x, y)
       
   348         };
       
   349     vgAppendPathData(iLinePath, 2, lineSegments, lineCoords);
       
   350     vgRemovePathCapabilities(iLinePath, VG_PATH_CAPABILITY_APPEND_TO);
       
   351     
       
   352     // Initialize a path for drawing borders
       
   353     iBorderPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 
       
   354                                11, 10 * 2, VG_PATH_CAPABILITY_APPEND_TO | VG_PATH_CAPABILITY_MODIFY);
       
   355 
       
   356     const VGubyte borderSegments[12] =
       
   357         {
       
   358         VG_MOVE_TO_ABS,
       
   359         VG_LINE_TO_REL,
       
   360         VG_LINE_TO_REL,
       
   361         VG_LINE_TO_REL,
       
   362         VG_LINE_TO_REL,
       
   363         VG_LINE_TO_REL,
       
   364         VG_LINE_TO_REL,
       
   365         VG_LINE_TO_REL,
       
   366         VG_LINE_TO_REL,
       
   367         VG_LINE_TO_REL,
       
   368         VG_LINE_TO_REL,
       
   369         VG_CLOSE_PATH,
       
   370         };
       
   371 
       
   372     const VGfloat borderCoords[10 * 2] = 
       
   373         {
       
   374         0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
       
   375         0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
       
   376         0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
       
   377         0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
       
   378         };
       
   379 
       
   380     vgAppendPathData(iBorderPath, 12, borderSegments, borderCoords);
       
   381     vgRemovePathCapabilities(iBorderPath, VG_PATH_CAPABILITY_APPEND_TO);
       
   382         
       
   383     // Get hardware configuration
       
   384     TInt hwConf = 0; // the defaulf value for everything is 0 to allow new flags to be defined
       
   385     HuiUtil::GetValueFromCentralRepository( KUIAccelTKHWConfigurationFlags, hwConf );
       
   386     if ( hwConf & KHuiAntialiasing )
       
   387         {
       
   388         SetQuality( EHuiQualityAccurate );
       
   389         }
       
   390     else
       
   391         {
       
   392         SetQuality( EHuiQualityFast );
       
   393         }
       
   394 
       
   395     
       
   396     iVgObjectsCreated = ETrue;
       
   397     }
       
   398  
       
   399 void CHuiVg10Gc::InitState()
       
   400     {
       
   401     // Clean matrix stack in case there is anything left
       
   402     // We can't construct a new stack here because we are not allowed to leave.
       
   403     // We keep the original stack and just delete the contents leaving one 
       
   404     // identity matrix that is always added when a new matrix stack is created
       
   405     TInt i = 0;
       
   406     // One identity matrix will remain.
       
   407     // When a new matrix stack is created, one identity matrix is added
       
   408     // It can never be removed, the code would panic.
       
   409     for ( i = 0; i < iMatrixStack->Count() - 2; i++ )
       
   410         {
       
   411         iMatrixStack->Pop(); 
       
   412         }
       
   413     // remove flags from stack, too.
       
   414     iMatrixFlagsStack.Reset();
       
   415 
       
   416     iScissorRect = TRect(0, 0, 0, 0);
       
   417     iMatrixFlags = 0;
       
   418     
       
   419     if (!iVgObjectsCreated)
       
   420         {
       
   421         TRAP_IGNORE(CreateVgObjectsL());    
       
   422         }
       
   423 
       
   424     // Default paint
       
   425     vgSetParameteri(iPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
       
   426     vgSetPaint(iPaint, VG_FILL_PATH | VG_STROKE_PATH);
       
   427         
       
   428     // Gradient paint
       
   429     vgSetParameteri(iGradientPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
       
   430         
       
   431     HUI_VG_INVARIANT();
       
   432     
       
   433     // Reset default state
       
   434     
       
   435     Enable(EFeatureBlending);
       
   436     Disable(EFeatureDepthTest);
       
   437 	iStateScissorTest = ETrue;    
       
   438     Disable(EFeatureClipping);
       
   439 
       
   440     // Use the image matrix as the primary matrix
       
   441     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
   442 
       
   443     RestoreState();
       
   444     HUI_VG_INVARIANT();
       
   445     }
       
   446 
       
   447 void CHuiVg10Gc::SetQuality(THuiQuality aQuality)
       
   448     {
       
   449     CHuiGc::SetQuality(aQuality);
       
   450     switch (Quality())
       
   451         {
       
   452         case EHuiQualityAccurate:
       
   453             vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_BETTER);
       
   454             vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
       
   455             break;
       
   456         case EHuiQualityFast:
       
   457             vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_FASTER);
       
   458             vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_FASTER);
       
   459             break;
       
   460         default:
       
   461             break;
       
   462         }
       
   463     HUI_VG_INVARIANT();
       
   464     }
       
   465 
       
   466 void CHuiVg10Gc::SetFillRule( THuiFillMode aFillMode )
       
   467     {   
       
   468     switch (aFillMode)
       
   469        {
       
   470        case EHuiFillNonZero:
       
   471            vgSeti(VG_FILL_RULE, VG_NON_ZERO);
       
   472            break;
       
   473        case EHuiFillEvenOdd:
       
   474            vgSeti(VG_FILL_RULE, VG_EVEN_ODD);
       
   475            break;
       
   476        default:
       
   477            break;
       
   478        }
       
   479     HUI_VG_INVARIANT();   
       
   480     }
       
   481 
       
   482 void CHuiVg10Gc::RestoreState() const
       
   483     {
       
   484     // Restore paint
       
   485     vgSetPaint(iPaint, VG_FILL_PATH | VG_STROKE_PATH);        
       
   486 
       
   487     // Restore scissor test state
       
   488     if(iStateScissorTest)
       
   489         {
       
   490         vgSeti(VG_SCISSORING, VG_TRUE);
       
   491         }
       
   492     else
       
   493         {
       
   494         vgSeti(VG_SCISSORING, VG_FALSE);
       
   495         }
       
   496     
       
   497     // Restore scissor rects
       
   498     // This fixes CHuiFxEffect cached draw
       
   499     TInt count = iClipRegion.Count();
       
   500     VGint coords[KHuiMaxVgScissorRects * 4];
       
   501 
       
   502     if(count > KHuiMaxVgScissorRects)
       
   503         {
       
   504         count = KHuiMaxVgScissorRects; //only 32 scissor rects supported    
       
   505         }
       
   506         
       
   507     TInt numberOfCoords = count*4;
       
   508     for ( TInt i = 0, j=0 ; i < numberOfCoords ; j++)
       
   509         { 
       
   510         coords[i++] = iClipRegion[j].iTl.iX;
       
   511         coords[i++] = iClipRegion[j].iTl.iY;
       
   512         coords[i++] = iClipRegion[j].Width();
       
   513         coords[i++] = iClipRegion[j].Height();      
       
   514         }
       
   515     
       
   516     vgSetiv(VG_SCISSOR_RECTS, numberOfCoords, coords);          
       
   517 
       
   518     HUI_VG_INVARIANT();
       
   519     }
       
   520 
       
   521 void CHuiVg10Gc::RestoreFlaggedState() const
       
   522     {
       
   523     // Get the changed stateflags from the renderplugin
       
   524     CHuiVg10RenderPlugin& renderer = (CHuiVg10RenderPlugin&) CHuiStatic::Renderer();
       
   525     TInt flags = renderer.GetRestoreStateFlags();
       
   526     
       
   527     // First a quick check, if nothing needs to be done
       
   528     if(!flags)
       
   529         {
       
   530         return;
       
   531         }
       
   532       
       
   533     // Check each flag and act accrodingly!
       
   534     if(flags & EHuiVg10GcStateFlagDirtyPaint)
       
   535         {
       
   536         // Restore paint
       
   537         vgSetPaint(iPaint, VG_FILL_PATH | VG_STROKE_PATH);
       
   538         }
       
   539 
       
   540     if(flags & EHuiVg10GcStateFlagDirtyScissor)
       
   541         {
       
   542         // Restore scissor test state
       
   543         if(iStateScissorTest)
       
   544             {
       
   545             vgSeti(VG_SCISSORING, VG_TRUE);
       
   546             }
       
   547         else
       
   548             {
       
   549             vgSeti(VG_SCISSORING, VG_FALSE);
       
   550             }
       
   551         }
       
   552     
       
   553     if(flags & EHuiVg10GcStateFlagDirtyScissorRects)
       
   554         {
       
   555         // Restore scissor rects
       
   556         TInt count = iClipRegion.Count();
       
   557         VGint coords[KHuiMaxVgScissorRects * 4];
       
   558 
       
   559         if(count > KHuiMaxVgScissorRects)
       
   560             {
       
   561             count = KHuiMaxVgScissorRects; //only 32 scissor rects supported    
       
   562             }
       
   563             
       
   564         TInt numberOfCoords = count*4;
       
   565         for ( TInt i = 0, j=0 ; i < numberOfCoords ; j++)
       
   566             { 
       
   567             coords[i++] = iClipRegion[j].iTl.iX;
       
   568             coords[i++] = iClipRegion[j].iTl.iY;
       
   569             coords[i++] = iClipRegion[j].Width();
       
   570             coords[i++] = iClipRegion[j].Height();      
       
   571             }
       
   572         
       
   573         vgSetiv(VG_SCISSOR_RECTS, numberOfCoords, coords);
       
   574         }
       
   575 
       
   576     // Clear the flags!
       
   577     renderer.ClearRestoreStateFlags();
       
   578     
       
   579     HUI_VG_INVARIANT();
       
   580     }
       
   581 
       
   582 void CHuiVg10Gc::UpdateProjection()
       
   583     {
       
   584     // Nothing to do
       
   585     }
       
   586 
       
   587 
       
   588 TInt CHuiVg10Gc::TextureUnits() const
       
   589     {
       
   590     return 1;
       
   591     }
       
   592 
       
   593 
       
   594 void CHuiVg10Gc::SetTextureUnits(TInt /*aTextureUnitCount*/)
       
   595     {
       
   596     // Nothing to do
       
   597     }
       
   598 
       
   599 
       
   600 void CHuiVg10Gc::Enable(TFeature aFeature, TBool aDoEnable)
       
   601     {
       
   602     HUI_VG_INVARIANT();
       
   603 
       
   604     switch(aFeature)
       
   605         {
       
   606         case EFeatureDepthTest:
       
   607             // Not supported
       
   608             break;
       
   609 
       
   610         case EFeatureDepthWrite:
       
   611             // Not supported
       
   612             break;
       
   613 
       
   614         case EFeatureTexturing:
       
   615             // Always enabled
       
   616             break;
       
   617 
       
   618         case EFeatureBlending:
       
   619             if(aDoEnable)
       
   620                 {
       
   621                 vgSeti(VG_BLEND_MODE, iBlendMode);
       
   622                 }
       
   623             else
       
   624                 {
       
   625                 vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
       
   626                 }
       
   627             break;
       
   628 
       
   629         case EFeatureClipping:
       
   630             if(aDoEnable)
       
   631                 {
       
   632                 // enable clipping
       
   633                 //if(!iStateScissorTest)
       
   634                 	{
       
   635                 	iStateScissorTest = ETrue;
       
   636                     vgSeti(VG_SCISSORING, VG_TRUE);
       
   637                 	}
       
   638                 }
       
   639             else
       
   640                 {
       
   641                 // disable clipping
       
   642                 //if(iStateScissorTest)
       
   643                 	{
       
   644                 	iStateScissorTest = EFalse;
       
   645                     vgSeti(VG_SCISSORING, VG_FALSE);
       
   646                 	}
       
   647                 
       
   648                 }
       
   649             break;
       
   650 
       
   651         case EFeatureAntialias:
       
   652             if(aDoEnable)
       
   653                 {
       
   654                 vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_BETTER);
       
   655                 }
       
   656             else
       
   657                 {
       
   658                 vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_FASTER);
       
   659                 }
       
   660             break;
       
   661 
       
   662         case EFeatureFog:
       
   663             // Not supported
       
   664             break;
       
   665 
       
   666         default:
       
   667             break;
       
   668         }
       
   669 
       
   670     HUI_VG_INVARIANT();
       
   671     }
       
   672 
       
   673 
       
   674 void CHuiVg10Gc::SetBlendMode(TBlendMode aBlendMode)
       
   675     {
       
   676     switch(aBlendMode)
       
   677         {
       
   678         case EBlendAdd:
       
   679             iBlendMode = VG_BLEND_ADDITIVE;
       
   680             break;
       
   681 
       
   682         default:
       
   683             iBlendMode = VG_BLEND_SRC_OVER;
       
   684             break;
       
   685         }
       
   686         vgSeti(VG_BLEND_MODE, iBlendMode);
       
   687     }
       
   688 
       
   689 
       
   690 void CHuiVg10Gc::SetTextureMode(TTextureMode aTextureMode, TReal32 /*aParam*/) __SOFTFP
       
   691     {
       
   692     switch(aTextureMode)
       
   693         {
       
   694         case ETextureModeNormal:
       
   695             break;
       
   696 
       
   697         default:
       
   698             break;
       
   699         }
       
   700 
       
   701     HUI_VG_INVARIANT();
       
   702     }
       
   703 
       
   704 
       
   705 void CHuiVg10Gc::SetDimmingFog(const TRgb& /*aColor*/, TReal32 /*aAmount*/) __SOFTFP
       
   706     {
       
   707     // Fog not supported
       
   708     }
       
   709 
       
   710 
       
   711 void CHuiVg10Gc::Clear()
       
   712     {
       
   713     HUI_VG_INVARIANT();
       
   714     TInt x = ProjectionViewport().iTl.iX;
       
   715     TInt y = ProjectionViewport().iTl.iY;
       
   716     TInt w = ProjectionViewport().Width();
       
   717     TInt h = ProjectionViewport().Height();
       
   718     VGfloat scale = 1.0f / 255.0f;
       
   719     VGfloat color[] = 
       
   720         {
       
   721         PenColor().Red()   * scale,
       
   722         PenColor().Green() * scale,
       
   723         PenColor().Blue()  * scale,
       
   724         PenAlpha() * scale
       
   725         };
       
   726     vgSetfv(VG_CLEAR_COLOR, 4, color);
       
   727     vgClear(x, y, w, h);
       
   728     HUI_VG_INVARIANT();
       
   729     }
       
   730 
       
   731 	
       
   732 void CHuiVg10Gc::ClearDepth()
       
   733     {
       
   734     Clear();
       
   735     }
       
   736 
       
   737 
       
   738 void CHuiVg10Gc::ClearColorAndDepth()
       
   739     {
       
   740     Clear();
       
   741     }
       
   742 
       
   743 // Do renderer specific initializations of the frame
       
   744 void CHuiVg10Gc::InitNewFrame()
       
   745 	{
       
   746 	LoadIdentity(EHuiGcMatrixModel);
       
   747 	}
       
   748 
       
   749 void CHuiVg10Gc::Clip(const TRect& aClipRect)
       
   750     {
       
   751     THuiRealRect transformed = aClipRect;
       
   752     
       
   753     HUI_DEBUGF4(_L("CHuiVg10Gc::Clip() - aClipRect     (%5i, %5i, %5i, %5i)"),
       
   754                 aClipRect.iTl.iX, aClipRect.iTl.iY,
       
   755                 aClipRect.iBr.iX, aClipRect.iBr.iY);
       
   756     
       
   757     // Transform the rectangle using our stacks
       
   758     UpdateClientMatrix();
       
   759     iMatrixStack->Current().Multiply(transformed.iTl);
       
   760     iMatrixStack->Current().Multiply(transformed.iBr);
       
   761     
       
   762     // Normalize the rectangle
       
   763     if (transformed.iTl.iX > transformed.iBr.iX)
       
   764     	{
       
   765     	TReal32 tmp = transformed.iTl.iX;
       
   766     	transformed.iTl.iX = transformed.iBr.iX;
       
   767     	transformed.iBr.iX = tmp;
       
   768     	}
       
   769     if (transformed.iTl.iY > transformed.iBr.iY)
       
   770     	{
       
   771     	TReal32 tmp = transformed.iTl.iY;
       
   772     	transformed.iTl.iY = transformed.iBr.iY;
       
   773     	transformed.iBr.iY = tmp;
       
   774     	}
       
   775 
       
   776     HUI_DEBUGF4(_L("CHuiVg10Gc::Clip() - Transformed = (%5.0f, %5.0f, %5.0f, %5.0f)"),
       
   777                 transformed.iTl.iX, transformed.iTl.iY,
       
   778                 transformed.iBr.iX, transformed.iBr.iY);
       
   779 
       
   780     CHuiGc::Clip(transformed.Round());
       
   781     HUI_VG_INVARIANT();
       
   782     }
       
   783 
       
   784 
       
   785 void CHuiVg10Gc::SetClip(const TRect& aClipRect)
       
   786     {
       
   787     iScissorRect = aClipRect;
       
   788     iScissorRect.Normalize();
       
   789     
       
   790     CHuiGc::SetClip(iScissorRect);
       
   791 
       
   792     VGint coords[4] = 
       
   793         {
       
   794         iScissorRect.iTl.iX,  iScissorRect.iTl.iY,
       
   795         iScissorRect.Width(), iScissorRect.Height()
       
   796         };
       
   797    
       
   798     Enable(EFeatureClipping);    
       
   799     vgSetiv(VG_SCISSOR_RECTS, 4, coords);
       
   800     HUI_VG_INVARIANT();
       
   801     }
       
   802 
       
   803 void CHuiVg10Gc::Clip(const TRegion& aRegion)
       
   804     {
       
   805     UpdateClientMatrix();
       
   806 
       
   807     iTempRegion.Clear();
       
   808     
       
   809     for (TInt i=0; i<aRegion.Count(); i++)
       
   810         {
       
   811         THuiRealRect transformed = aRegion[i];
       
   812         iMatrixStack->Current().Multiply(transformed.iTl);
       
   813         iMatrixStack->Current().Multiply(transformed.iBr);
       
   814         
       
   815         // Normalize the rectangle
       
   816         if (transformed.iTl.iX > transformed.iBr.iX)
       
   817         	{
       
   818         	TReal32 tmp = transformed.iTl.iX;
       
   819         	transformed.iTl.iX = transformed.iBr.iX;
       
   820         	transformed.iBr.iX = tmp;
       
   821         	}
       
   822         if (transformed.iTl.iY > transformed.iBr.iY)
       
   823         	{
       
   824         	TReal32 tmp = transformed.iTl.iY;
       
   825         	transformed.iTl.iY = transformed.iBr.iY;
       
   826         	transformed.iBr.iY = tmp;
       
   827         	}            
       
   828         
       
   829         iTempRegion.AddRect(transformed.Round());
       
   830         }
       
   831 	    
       
   832 	CHuiGc::Clip(iTempRegion);	    
       
   833     
       
   834     HUI_VG_INVARIANT();
       
   835     }
       
   836     
       
   837 void CHuiVg10Gc::SetClipRegion(const TRegion& aRegion)
       
   838     {
       
   839     TInt count = aRegion.Count();
       
   840     VGint coords[KHuiMaxVgScissorRects * 4];
       
   841 
       
   842     if(count > KHuiMaxVgScissorRects)
       
   843         {
       
   844         count = KHuiMaxVgScissorRects; //only 32 scissor rects supported    
       
   845         }
       
   846         
       
   847     TInt numberOfCoords = count*4;
       
   848     for ( TInt i = 0, j=0 ; i < numberOfCoords ; j++)
       
   849         { 
       
   850         coords[i++] = aRegion[j].iTl.iX;
       
   851         coords[i++] = aRegion[j].iTl.iY;
       
   852         coords[i++] = aRegion[j].Width();
       
   853         coords[i++] = aRegion[j].Height();      
       
   854         }
       
   855     
       
   856     CHuiGc::SetClipRegion(aRegion);     
       
   857     
       
   858     Enable(EFeatureClipping);    
       
   859     vgSetiv(VG_SCISSOR_RECTS, numberOfCoords, coords);          
       
   860     
       
   861     HUI_VG_INVARIANT();
       
   862     }
       
   863 
       
   864 void CHuiVg10Gc::CancelClipping()
       
   865     {
       
   866     Disable(EFeatureClipping);    
       
   867     }
       
   868 
       
   869 void CHuiVg10Gc::DrawText(const CHuiTextMesh& aTextMesh,
       
   870                           const THuiRealRect& aBounds,
       
   871                           TReal32 aShadow) __SOFTFP
       
   872     {
       
   873     CHuiGc::DrawText(aTextMesh, aBounds, aShadow);
       
   874     }
       
   875 
       
   876 
       
   877 /**
       
   878  *  Given a THuiImage, return the corresponding VGImage or 
       
   879  *  VG_INVALID_HANDLE if there is none.
       
   880  */
       
   881 static VGImage GetVGImageFromTexture(const MHuiSegmentedTexture& aTexture)
       
   882     {
       
   883     if (aTexture.SegmentCount() == 1)
       
   884         {
       
   885         return (VGImage)aTexture.SegmentName(0);
       
   886         }
       
   887     return VG_INVALID_HANDLE;
       
   888     }
       
   889 
       
   890 
       
   891 /**
       
   892  *  Construct a source rectangle based on the texture coordinates
       
   893  *  specified for an image.
       
   894  */
       
   895 static THuiRealRect GetSourceRectangleFromImage(const THuiImage& aImage)
       
   896     {
       
   897     TReal32 texCoords[8];
       
   898     aImage.GetTexCoords(texCoords);
       
   899     THuiRealRect sourceRect;
       
   900     
       
   901     sourceRect.iTl.iX = texCoords[0];
       
   902     sourceRect.iTl.iY = texCoords[1];
       
   903     sourceRect.iBr.iX = texCoords[4];
       
   904     sourceRect.iBr.iY = texCoords[5];
       
   905     
       
   906     return sourceRect;
       
   907     }
       
   908 
       
   909 void CHuiVg10Gc::DoDrawImage(const THuiImage& aImage,
       
   910                              const THuiRealPoint& aTopLeft,
       
   911                              const THuiRealSize& aSize)
       
   912     {
       
   913     if(!aImage.HasTexture())
       
   914         {
       
   915         return;
       
   916         }
       
   917     
       
   918     // Fetch the texture coordinates from the image
       
   919     THuiRealRect destRect(aTopLeft, aSize);
       
   920     THuiRealRect sourceRect(GetSourceRectangleFromImage(aImage));
       
   921     DrawTexture(aImage.Texture(), sourceRect, destRect);
       
   922     }
       
   923 
       
   924 
       
   925 void CHuiVg10Gc::DoDrawImages(const THuiImage& aImage,
       
   926                                 const THuiImage& aImage2,
       
   927                                 const THuiRealPoint& aTopLeft,
       
   928                                 const THuiRealSize& aSize)
       
   929     {
       
   930     DoDrawImage(aImage,  aTopLeft, aSize);
       
   931     DoDrawImage(aImage2, aTopLeft, aSize);
       
   932     }
       
   933 
       
   934 
       
   935 void CHuiVg10Gc::UpdateColor(TReal32 /*aAlphaFactor*/) __SOFTFP
       
   936     {
       
   937     VGuint color = (PenColor().Internal() << 8) | PenAlpha();
       
   938     
       
   939 #if defined(RENDER_DEBUG_RECTANGLES)
       
   940     color = Math::Random() | 0xff;
       
   941 #endif
       
   942     
       
   943     // Update the color of the current paint
       
   944     vgSetColor(iPaint, color);
       
   945     
       
   946     // Detect white fully opaque color
       
   947     if (color == 0xffffffff)
       
   948         {
       
   949         vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
       
   950         }
       
   951     else
       
   952         {
       
   953         vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
       
   954         }
       
   955     HUI_VG_INVARIANT();
       
   956     }
       
   957 
       
   958 void CHuiVg10Gc::DrawCroppedTexture(const MHuiSegmentedTexture& aTexture, const THuiRealRect& aSourceRect,
       
   959                                     const THuiRealRect& aDestRect)
       
   960     {
       
   961     // Render state which affects what we do here (roughly decreasing order of probability):
       
   962     // - Source cropping
       
   963     // - Color modulation
       
   964     // - Alpha modulation
       
   965     // - Affine matrix transform (i.e. other than scale or translation)
       
   966     //
       
   967     // Difficult combinations:
       
   968     // - Source cropping with color or alpha modulation
       
   969     //   - Option 1: Create a child image from the cropped region
       
   970     //     - Can't do this because the cropping region is in floating point coords.
       
   971     //     - Performance overhead possibly non-negligible.
       
   972     //   - Option 2: Use scissoring to do the cropping
       
   973     //     - Does not work for rotate/skew transform.
       
   974     //   - Option 3: Use a mask to do the cropping
       
   975     //     - Auxiliary mask bitmap needed, possible performance hit.
       
   976     //   - Option 4: Use a pattern paint
       
   977     //     - Color/alpha modulation requires an offscreen image.
       
   978     // - Resolution: Go with option 2 and option 1 if rotation/skewing is in effect.
       
   979     TSize imageSize = aTexture.Size();
       
   980     VGfloat srcW   = aSourceRect.Width()  * imageSize.iWidth;
       
   981     VGfloat srcH   = aSourceRect.Height() * imageSize.iHeight;
       
   982     VGfloat srcX   = aSourceRect.iTl.iX   * imageSize.iWidth;
       
   983     VGfloat srcY   = aSourceRect.iTl.iY   * imageSize.iHeight;
       
   984 
       
   985     // Make sure the source rectangle is not degenerate
       
   986     srcW = Max(1.0f, srcW);
       
   987     srcH = Max(1.0f, srcH);
       
   988     
       
   989     VGfloat scaleX = aDestRect.Width()  / srcW;
       
   990     VGfloat scaleY = aDestRect.Height() / srcH;
       
   991     VGImage image = VG_INVALID_HANDLE;
       
   992     
       
   993 	// Check if OpenVg state has changed
       
   994     RestoreFlaggedState();
       
   995     
       
   996 #ifdef __NVG
       
   997     const CHuiVg10Texture& texture = static_cast<const CHuiVg10Texture&>( aTexture );
       
   998     TBool isExtended = texture.IsExtended();
       
   999 #endif
       
  1000     
       
  1001     // Getting the vgImage out of the texture
       
  1002     image = GetVGImageFromTexture( aTexture );
       
  1003     
       
  1004     if (iMatrixFlags & EMatrixFlagsRotation)
       
  1005         {
       
  1006         VGImage tmpImage = vgChildImage(image, (VGint)srcX, imageSize.iHeight - (VGint)srcY - (VGint)srcH, (VGint)srcW, (VGint)srcH);
       
  1007         
       
  1008         if (tmpImage == VG_INVALID_HANDLE)
       
  1009             {
       
  1010             HUI_DEBUG(_L("CHuiVg10Gc::DrawCroppedTexture() - Unable to create temporary child image."));
       
  1011             // We cannot leave because we are called by a non-leaving exported function
       
  1012             // If we cannot draw, we just return without doing anything.
       
  1013             return;
       
  1014             }
       
  1015         HUI_VG_INVARIANT();
       
  1016         
       
  1017         // Render the child image
       
  1018         Push(EHuiGcMatrixModel);
       
  1019 #if !defined(RENDER_DEBUG_RECTANGLES)
       
  1020         vgTranslate(aDestRect.iTl.iX, aDestRect.iTl.iY);
       
  1021         vgScale(scaleX, scaleY);
       
  1022         vgDrawImage(tmpImage);
       
  1023 #else
       
  1024         TRect d(aDestRect.iTl.iX, aDestRect.iTl.iY, aDestRect.iBr.iX, aDestRect.iBr.iY);
       
  1025         DrawRect(d);
       
  1026 #endif
       
  1027         Pop(EHuiGcMatrixModel);
       
  1028         
       
  1029         vgDestroyImage(tmpImage);
       
  1030         HUI_VG_INVARIANT();
       
  1031         return;
       
  1032         }
       
  1033     
       
  1034     // Set a scissor rectangle that corresponds with the target rectangle
       
  1035     TBool clippingWasEnabled = iStateScissorTest;
       
  1036     
       
  1037     if (!clippingWasEnabled)
       
  1038         {
       
  1039         Enable(EFeatureClipping);    
       
  1040         }
       
  1041     
       
  1042     PushClip();
       
  1043     Clip(aDestRect);    
       
  1044     
       
  1045     // Render the image
       
  1046     Push(EHuiGcMatrixModel);
       
  1047 #if !defined(RENDER_DEBUG_RECTANGLES)
       
  1048     vgTranslate(aDestRect.iTl.iX, aDestRect.iTl.iY);
       
  1049     vgScale(scaleX, scaleY);
       
  1050     vgTranslate(-srcX, -srcY);
       
  1051 
       
  1052 #ifdef __NVG
       
  1053     if ( isExtended && texture.IsNvgContent())
       
  1054         {
       
  1055         // Determine the size to which we want to draw the NVG icon paths
       
  1056         TSize contentSize( HUI_ROUND_FLOAT_TO_INT(aDestRect.Width()),
       
  1057                 HUI_ROUND_FLOAT_TO_INT(aDestRect.Height()) );
       
  1058         UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1059         // Draw the NVG data (be it either the object cached commands or the "normal" nvg data)
       
  1060         DrawNVG(texture.GetExtendedTextureData(), texture.GetIconCommandsData(), contentSize, EFalse);
       
  1061         }
       
  1062     else
       
  1063         {
       
  1064         if (image != VG_INVALID_HANDLE)
       
  1065             {
       
  1066             //HUI_DEBUG1(_L("HuiVg10Gc::DrawCroppedTexture - drawing with vgDrawImage(%d) instead of DrawNVG"), image);
       
  1067             vgDrawImage(image);
       
  1068             }
       
  1069         else
       
  1070             {
       
  1071             HUI_DEBUG1(_L("HuiVg10Gc::DrawCroppedTexture - INVALID HANDLE, vgDrawImage() not called!"), image);
       
  1072             }
       
  1073         }
       
  1074 #else
       
  1075     vgDrawImage(image);
       
  1076 #endif // __NVG
       
  1077 
       
  1078 #else // RENDER_DEBUG_RECTANGLES
       
  1079     TRect d(aDestRect.iTl.iX, aDestRect.iTl.iY, aDestRect.iBr.iX, aDestRect.iBr.iY);
       
  1080     DrawRect(d);
       
  1081 #endif
       
  1082     HUI_VG_INVARIANT();
       
  1083     Pop(EHuiGcMatrixModel);
       
  1084     
       
  1085     // Restore state
       
  1086     PopClip();
       
  1087 
       
  1088     if (!clippingWasEnabled)
       
  1089         {
       
  1090         Disable(EFeatureClipping);    
       
  1091         }
       
  1092     
       
  1093     HUI_VG_INVARIANT();
       
  1094     
       
  1095 #if 0
       
  1096     // Crop implementation using a paint pattern
       
  1097     // TODO: Handle color modulation + cropping
       
  1098     VGfloat srcW   = aSourceRect.Width()  * aImage.Texture().Size().iWidth;
       
  1099     VGfloat srcH   = aSourceRect.Height() * aImage.Texture().Size().iHeight;
       
  1100     VGfloat srcX   = aSourceRect.iTl.iX   * aImage.Texture().Size().iWidth;
       
  1101     VGfloat srcY   = aSourceRect.iTl.iY   * aImage.Texture().Size().iHeight;
       
  1102     VGfloat scaleX = aDestRect.Width()  / srcW;
       
  1103     VGfloat scaleY = aDestRect.Height() / srcH;
       
  1104     VGImage image  = GetVGImageFromTexture(aTexture);
       
  1105 
       
  1106     vgPaintPattern(iPaint, image);
       
  1107     
       
  1108     // Transform the paint pattern to fill the destination rectangle as required
       
  1109     vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
  1110     vgLoadIdentity();
       
  1111     vgTranslate(aDestRect.iTl.iX, aDestRect.iTl.iY);
       
  1112     vgScale(scaleX, scaleY);
       
  1113     vgTranslate(-srcX, -srcY);
       
  1114     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  1115     
       
  1116     // Update the path transformation matrix
       
  1117     UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1118 
       
  1119     // Draw a rectangle which is filled with the image as a pattern
       
  1120     const VGfloat coords[] = 
       
  1121         {
       
  1122         aDestRect.iTl.iX, aDestRect.iTl.iY,
       
  1123         aDestRect.Width(), 0,
       
  1124         0, aDestRect.Height(),
       
  1125         -aDestRect.Width(), 0,
       
  1126         };
       
  1127     vgModifyPathCoords(iImagePath, 0, 5, coords);
       
  1128     vgDrawPath(iImagePath, VG_FILL_PATH);
       
  1129     
       
  1130     // Restore the state
       
  1131     vgPaintPattern(iPaint, VG_INVALID_HANDLE);
       
  1132     UpdateColor();
       
  1133     vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
  1134     vgLoadIdentity();
       
  1135     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  1136     HUI_VG_INVARIANT();
       
  1137 #endif
       
  1138     }
       
  1139 
       
  1140 void CHuiVg10Gc::DrawTexture(const MHuiSegmentedTexture& aTexture, 
       
  1141                              const THuiRealRect& aSourceRect, 
       
  1142                              const THuiRealRect& aDestRect)
       
  1143     {
       
  1144     // See if the image is cropped
       
  1145     const VGfloat epsilon = 1e-3;
       
  1146     if (aSourceRect.iTl.iX > epsilon || 
       
  1147         aSourceRect.iTl.iY > epsilon ||
       
  1148         aSourceRect.iBr.iX < 1.0f - epsilon ||
       
  1149         aSourceRect.iBr.iY < 1.0f - epsilon)
       
  1150         {
       
  1151         DrawCroppedTexture(aTexture, aSourceRect, aDestRect);
       
  1152         return;
       
  1153         }
       
  1154 
       
  1155 	// Check if OpenVg state has changed
       
  1156     RestoreFlaggedState();
       
  1157     
       
  1158     Push(EHuiGcMatrixModel);
       
  1159 #if !defined(RENDER_DEBUG_RECTANGLES)
       
  1160     vgTranslate(aDestRect.iTl.iX, aDestRect.iTl.iY);
       
  1161     
       
  1162 #ifdef __NVG
       
  1163     const CHuiVg10Texture& texture = static_cast<const CHuiVg10Texture&>( aTexture );
       
  1164     TBool isExtended = texture.IsExtended();
       
  1165     
       
  1166     if (isExtended && texture.IsNvgContent())
       
  1167         {
       
  1168         UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1169         TSize contentSize(0, 0);
       
  1170         contentSize.SetSize( HUI_ROUND_FLOAT_TO_INT( aDestRect.Width() ),
       
  1171             HUI_ROUND_FLOAT_TO_INT( aDestRect.Height() ) );
       
  1172         // Draw the NVG data (be it either the object cached commands or the "normal" nvg data)
       
  1173         DrawNVG(texture.GetExtendedTextureData(), texture.GetIconCommandsData(), contentSize, EFalse);
       
  1174         }
       
  1175     else
       
  1176         {
       
  1177         // "Option C" -way
       
  1178         VGfloat scaleX = aDestRect.Width()  / aTexture.Size().iWidth;
       
  1179         VGfloat scaleY = aDestRect.Height() / aTexture.Size().iHeight;
       
  1180         VGImage image = GetVGImageFromTexture( aTexture );
       
  1181 
       
  1182         if (image != VG_INVALID_HANDLE)
       
  1183             {
       
  1184             vgScale(scaleX, scaleY);
       
  1185             vgDrawImage(image);
       
  1186             //HUI_DEBUG1(_L("HuiVg10Gc::DrawTexture - vgDrawImage(%d) drawn!"), image);
       
  1187             }
       
  1188         else
       
  1189             {
       
  1190             HUI_DEBUG(_L("HuiVg10Gc::DrawTexture - INVALID HANDLE, vgDrawImage() not called!"));
       
  1191             }
       
  1192         }
       
  1193 #else
       
  1194     // TODO: Fast paths for unit scale and opaque blending
       
  1195     VGfloat scaleX = aDestRect.Width()  / aTexture.Size().iWidth;
       
  1196     VGfloat scaleY = aDestRect.Height() / aTexture.Size().iHeight;
       
  1197     VGImage image = GetVGImageFromTexture(aTexture);
       
  1198     
       
  1199     vgScale(scaleX, scaleY);
       
  1200     vgDrawImage(image);
       
  1201 #endif // __NVG
       
  1202     
       
  1203 #else
       
  1204     TRect d(aDestRect.iTl.iX, aDestRect.iTl.iY, aDestRect.iBr.iX, aDestRect.iBr.iY);
       
  1205     DrawRect(d);
       
  1206 #endif
       
  1207 
       
  1208     HUI_VG_INVARIANT();
       
  1209     Pop(EHuiGcMatrixModel);
       
  1210     }
       
  1211 
       
  1212 void CHuiVg10Gc::DrawStretchImage(TStretchMode aMode,
       
  1213                                   const THuiImage& aImage, 
       
  1214                                   const THuiRealRect& aRect,
       
  1215                                   TInt aStartWidth, 
       
  1216                                   TInt aEndWidth)
       
  1217     {
       
  1218     if (!aImage.HasTexture())
       
  1219         {
       
  1220         return;
       
  1221         }
       
  1222 
       
  1223     UpdateColor();
       
  1224 
       
  1225     THuiRealPoint aTopLeft(aRect.iTl);
       
  1226     THuiRealSize  aSize(aRect.iBr.iX - aRect.iTl.iX, aRect.iBr.iY - aRect.iTl.iY);
       
  1227     THuiRealRect sourceRect(GetSourceRectangleFromImage(aImage));
       
  1228     THuiRealSize imageSize = aImage.Texture().Size();
       
  1229     
       
  1230 	switch(aMode) 
       
  1231 		{
       
  1232 	    case EStretchFull:
       
  1233 			{
       
  1234 			DrawTexture(aImage.Texture(), sourceRect, aRect);
       
  1235 	    	break;
       
  1236 			}
       
  1237 				    
       
  1238 	    case EStretchVertical:
       
  1239 	        {
       
  1240             THuiRealRect destRect(aRect);
       
  1241             if (aStartWidth > 0)
       
  1242                 {
       
  1243                 THuiRealRect edgeDestRect(aRect);
       
  1244                 THuiRealRect edgeSourceRect(sourceRect);
       
  1245                 edgeDestRect.iBr.iY   = edgeDestRect.iTl.iY   + aStartWidth;
       
  1246                 edgeSourceRect.iBr.iY = edgeSourceRect.iTl.iY + aStartWidth / imageSize.iHeight;
       
  1247                 DrawTexture(aImage.Texture(), edgeSourceRect, edgeDestRect);
       
  1248                 destRect.iTl.iY   += aStartWidth;
       
  1249                 sourceRect.iTl.iY += aStartWidth / imageSize.iHeight;
       
  1250                 }
       
  1251             if (aEndWidth > 0)
       
  1252                 {
       
  1253                 THuiRealRect edgeDestRect(aRect);
       
  1254                 THuiRealRect edgeSourceRect(sourceRect);
       
  1255                 edgeDestRect.iTl.iY   = edgeDestRect.iBr.iY   - aEndWidth;
       
  1256                 edgeSourceRect.iTl.iY = edgeSourceRect.iBr.iY - aEndWidth / imageSize.iHeight;
       
  1257                 DrawTexture(aImage.Texture(), edgeSourceRect, edgeDestRect);
       
  1258                 destRect.iBr.iY   -= aEndWidth;
       
  1259                 sourceRect.iBr.iY -= aEndWidth / imageSize.iHeight;
       
  1260                 }
       
  1261             DrawTexture(aImage.Texture(), sourceRect, destRect);
       
  1262 	        break;
       
  1263 	        }
       
  1264 	    case EStretchHorizontal:
       
  1265 	        {
       
  1266             THuiRealRect destRect(aRect);
       
  1267             if (aStartWidth > 0)
       
  1268                 {
       
  1269                 THuiRealRect edgeDestRect(aRect);
       
  1270                 THuiRealRect edgeSourceRect(sourceRect);
       
  1271                 edgeDestRect.iBr.iX   = edgeDestRect.iTl.iX   + aStartWidth;
       
  1272                 edgeSourceRect.iBr.iX = edgeSourceRect.iTl.iX + aStartWidth / imageSize.iWidth;
       
  1273                 DrawTexture(aImage.Texture(), edgeSourceRect, edgeDestRect);
       
  1274                 destRect.iTl.iX   += aStartWidth;
       
  1275                 sourceRect.iTl.iX += aStartWidth / imageSize.iWidth;
       
  1276                 }
       
  1277             if (aEndWidth > 0)
       
  1278                 {
       
  1279                 THuiRealRect edgeDestRect(aRect);
       
  1280                 THuiRealRect edgeSourceRect(sourceRect);
       
  1281                 edgeDestRect.iTl.iX   = edgeDestRect.iBr.iX   - aEndWidth;
       
  1282                 edgeSourceRect.iTl.iX = edgeSourceRect.iBr.iX - aEndWidth / imageSize.iWidth;
       
  1283                 DrawTexture(aImage.Texture(), edgeSourceRect, edgeDestRect);
       
  1284                 destRect.iBr.iX   -= aEndWidth;
       
  1285                 sourceRect.iBr.iX -= aEndWidth / imageSize.iWidth;
       
  1286                 }
       
  1287             DrawTexture(aImage.Texture(), sourceRect, destRect);
       
  1288 	        break;
       
  1289 	        }
       
  1290 	
       
  1291 	    default:
       
  1292 	        HUI_DEBUG(_L("CHuiVg10Gc::DrawStretchImage() - ERROR! Tried to use stretch mode that hasn't been implemented. Panicing."));
       
  1293 		    HUI_PANIC(THuiPanic::ENotImplemented);
       
  1294 	}
       
  1295     
       
  1296     HUI_VG_INVARIANT();
       
  1297     }
       
  1298 
       
  1299 void CHuiVg10Gc::DrawRect(const TRect& aRect)
       
  1300     {
       
  1301     if (iPaintPattern)
       
  1302         {        
       
  1303         // Add 0.5 to all coordinates to get them in the middle of pixels 
       
  1304         TRect rect = aRect;
       
  1305         rect.iTl.iX += 0.5f;
       
  1306         rect.iTl.iY += 0.5f;
       
  1307         rect.iBr.iX -= 0.5f;
       
  1308         rect.iBr.iY -= 0.5f;
       
  1309         
       
  1310         const VGfloat coords[] = {
       
  1311                 rect.iTl.iX + 0.5f, rect.iTl.iY + 0.5f,
       
  1312                 rect.Width(), 0.0f,
       
  1313                 0.0f, rect.Height(),
       
  1314                 -rect.Width(), 0.0f,
       
  1315             };
       
  1316 
       
  1317         UpdateColor();
       
  1318         UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1319         
       
  1320         UsePaintPattern();
       
  1321         
       
  1322         vgModifyPathCoords(iRectPath, 0, 4, coords);
       
  1323         vgDrawPath(iRectPath, VG_FILL_PATH);
       
  1324         
       
  1325         // Restore rect path
       
  1326         const VGfloat rectCoords[] = 
       
  1327             {
       
  1328              0.0f, 0.0f,             // (x, y)
       
  1329              1.0f, 0.0f,             // (width, 0)
       
  1330              0.0f, 1.0f,             // (0, height)
       
  1331             -1.0f, 0.0f,             // (-width, 0)
       
  1332             };
       
  1333 
       
  1334         vgModifyPathCoords(iRectPath, 0, 4, rectCoords);        
       
  1335 
       
  1336         DiscardPaintPattern();
       
  1337         }
       
  1338     else
       
  1339         {
       
  1340         // fast path (doen not work with patterned fill)
       
  1341         UpdateColor();
       
  1342         UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1343         vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1344     
       
  1345         vgTranslate(aRect.iTl.iX, aRect.iTl.iY);
       
  1346         vgScale(aRect.Width(),aRect.Height());
       
  1347     
       
  1348         vgDrawPath(iRectPath, VG_FILL_PATH);
       
  1349     
       
  1350         vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  1351         UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1352         }
       
  1353 
       
  1354     HUI_VG_INVARIANT();
       
  1355     }
       
  1356 
       
  1357 void CHuiVg10Gc::DrawPolygon( RArray<THuiRealPoint>& aPoints )
       
  1358     {
       
  1359     
       
  1360     // use the path intended for dynamic shapes
       
  1361     // it has type float and can hold any number of segments
       
  1362        
       
  1363     TInt count = aPoints.Count();
       
  1364     VGfloat* coords = NULL;
       
  1365     coords = new VGfloat[count * 2];
       
  1366     
       
  1367     VGubyte* segments = NULL;
       
  1368     segments = new VGubyte[count + 1];
       
  1369     
       
  1370     if ( !coords || !segments )
       
  1371         {
       
  1372         // ran out of memory, must just return
       
  1373         delete[] coords;
       
  1374         delete[] segments;
       
  1375         return;
       
  1376         }
       
  1377     
       
  1378     for( TInt i = 0; i < count; i++ )
       
  1379     	{
       
  1380 	    coords[2 * i] = aPoints[i].iX;
       
  1381 	    coords[2 * i + 1] = aPoints[i].iY;
       
  1382 	    segments[i] = VG_LINE_TO_ABS;
       
  1383     	}
       
  1384     // fix the first segment into move instead of draw	
       
  1385     segments[0] = VG_MOVE_TO_ABS;
       
  1386     // the last segment closes the path to get a solid object
       
  1387     segments[count] = VG_CLOSE_PATH;
       
  1388     
       
  1389     UpdateColor();
       
  1390     UpdateMatrix( VG_MATRIX_PATH_USER_TO_SURFACE );
       
  1391     
       
  1392     UsePaintPattern(); 
       
  1393     
       
  1394     vgAppendPathData( iPath, count + 1, segments, coords);
       
  1395 
       
  1396     vgDrawPath( iPath, VG_FILL_PATH );
       
  1397     vgClearPath( iPath, VG_PATH_CAPABILITY_APPEND_TO );
       
  1398 
       
  1399     DiscardPaintPattern();
       
  1400     
       
  1401     // don't leak memory
       
  1402     delete[] coords;
       
  1403     delete[] segments;
       
  1404         
       
  1405     HUI_VG_INVARIANT();
       
  1406 
       
  1407     }    
       
  1408 
       
  1409 void CHuiVg10Gc::DrawLine(const TPoint& aStart,
       
  1410                           const TPoint& aEnd,
       
  1411                           const TInt aThickness)
       
  1412     {
       
  1413 
       
  1414     // Add 0.5 to all coordinates to get them in the middle of pixels 
       
  1415     const VGfloat coords[] = {
       
  1416             aStart.iX + 0.5f, aStart.iY + 0.5f,
       
  1417             aEnd.iX + 0.5f, aEnd.iY + 0.5f,
       
  1418         };
       
  1419     
       
  1420     UpdateColor();
       
  1421     UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1422     
       
  1423     vgModifyPathCoords(iLinePath, 0, 2, coords);
       
  1424     vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_SQUARE);
       
  1425     vgSeti(VG_STROKE_LINE_WIDTH, aThickness);
       
  1426     vgDrawPath(iLinePath, VG_STROKE_PATH);
       
  1427     HUI_VG_INVARIANT();
       
  1428     }
       
  1429 
       
  1430 void CHuiVg10Gc::DrawEllipse(const TRect& aRect, THuiFillMode aDrawMode, const TInt aThickness)
       
  1431     {
       
  1432     // Fix given destination rect to be in th middle of openvg pixels
       
  1433     THuiRealRect destinationRect = aRect;
       
  1434     destinationRect.iTl.iX += 0.5f;
       
  1435     destinationRect.iTl.iY += 0.5f;
       
  1436     destinationRect.iBr.iX -= 0.5f;
       
  1437     destinationRect.iBr.iY -= 0.5f;
       
  1438     
       
  1439     VGfloat alpha = PenAlpha();
       
  1440     vgClearPath(iEllipsePath, VG_PATH_CAPABILITY_APPEND_TO);
       
  1441     
       
  1442     VGfloat cx = (destinationRect.iTl.iX + destinationRect.iBr.iX) / 2.f; 
       
  1443     VGfloat cy  = (destinationRect.iTl.iY + destinationRect.iBr.iY) / 2.f;
       
  1444     VGfloat width = destinationRect.Width();
       
  1445     VGfloat height = destinationRect.Height();
       
  1446     
       
  1447     vguEllipse(iEllipsePath, cx, cy, width, height);
       
  1448    
       
  1449     UpdateColor();
       
  1450     UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1451     
       
  1452     TInt oldThickness = vgGeti(VG_STROKE_LINE_WIDTH);
       
  1453     if(oldThickness != aThickness)
       
  1454         {
       
  1455         vgSeti(VG_STROKE_LINE_WIDTH, aThickness);
       
  1456         }
       
  1457     VGPaint paint;
       
  1458     if (aDrawMode != EHuiNoFill)
       
  1459         {
       
  1460         paint = vgGetPaint(VG_FILL_PATH);
       
  1461         }
       
  1462      else
       
  1463         {
       
  1464         paint = vgGetPaint(VG_STROKE_PATH);
       
  1465         }
       
  1466 
       
  1467     VGfloat color[4], modifiedColor[4];
       
  1468     
       
  1469     if (paint != VG_INVALID_HANDLE)
       
  1470        {
       
  1471        vgGetParameterfv(paint, VG_PAINT_COLOR, 4, color);
       
  1472        if (color[3]!=alpha)
       
  1473            {
       
  1474            modifiedColor[0] = color[0];
       
  1475            modifiedColor[1] = color[1];
       
  1476            modifiedColor[2] = color[2];
       
  1477            modifiedColor[3] = alpha;
       
  1478            vgSetParameterfv(paint, VG_PAINT_COLOR, 4, modifiedColor);
       
  1479            }
       
  1480        else
       
  1481            {
       
  1482            // no reason to set back the old color. it is the same.
       
  1483            paint = VG_INVALID_HANDLE; 
       
  1484            }
       
  1485        }
       
  1486 
       
  1487     UsePaintPattern();
       
  1488     
       
  1489     if (aDrawMode != EHuiNoFill)
       
  1490         {
       
  1491         vgDrawPath(iEllipsePath, VG_FILL_PATH);
       
  1492         }
       
  1493     else
       
  1494         {
       
  1495         vgDrawPath(iEllipsePath, VG_STROKE_PATH);
       
  1496         }
       
  1497 
       
  1498     DiscardPaintPattern();
       
  1499     
       
  1500     if (paint != VG_INVALID_HANDLE)
       
  1501         {
       
  1502         vgSetParameterfv(paint, VG_PAINT_COLOR, 4, color);
       
  1503         HUI_VG_INVARIANT();
       
  1504         }
       
  1505     if(oldThickness != aThickness)
       
  1506         {
       
  1507         vgSeti(VG_STROKE_LINE_WIDTH, oldThickness);
       
  1508         }
       
  1509     HUI_VG_INVARIANT();
       
  1510     
       
  1511     }
       
  1512 
       
  1513 void CHuiVg10Gc::DrawArc(const TRect& aRect, THuiFillMode aDrawMode, const TInt aThickness, TReal32 aStart, TReal32 aEnd, TBool aIsPie)
       
  1514     {
       
  1515     // Fix given destination rect to be in th middle of openvg pixels
       
  1516     THuiRealRect destinationRect = aRect;
       
  1517     destinationRect.iTl.iX += 0.5f;
       
  1518     destinationRect.iTl.iY += 0.5f;
       
  1519     destinationRect.iBr.iX -= 0.5f;
       
  1520     destinationRect.iBr.iY -= 0.5f;
       
  1521     
       
  1522     VGfloat alpha = PenAlpha() / 255.f;
       
  1523     vgClearPath(iArcPath, VG_PATH_CAPABILITY_APPEND_TO);
       
  1524     
       
  1525     VGfloat cx = (destinationRect.iTl.iX + destinationRect.iBr.iX) / 2.f; 
       
  1526     VGfloat cy  = (destinationRect.iTl.iY + destinationRect.iBr.iY) / 2.f;
       
  1527     VGfloat width = destinationRect.Width();
       
  1528     VGfloat height = destinationRect.Height();
       
  1529     
       
  1530     VGUArcType arcType = aIsPie ? VGU_ARC_PIE : VGU_ARC_OPEN;
       
  1531 
       
  1532     // Ready to draw the arc. Note that in OpenVG, y axis points upwards. Anti-clockwise goes
       
  1533     // is towards positive direction. The method CHuiVg10CanvasGc::DoDrawPieAndArc made sure that 
       
  1534     // angleExtent is always positive.
       
  1535     TReal32 angleExtent = aEnd - aStart;
       
  1536     vguArc(iArcPath, cx, cy, width, height, aStart, angleExtent, arcType);
       
  1537    
       
  1538     UpdateColor();
       
  1539     UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1540     
       
  1541     TInt oldThickness = vgGeti(VG_STROKE_LINE_WIDTH);
       
  1542     if(oldThickness != aThickness)
       
  1543         {
       
  1544         vgSeti(VG_STROKE_LINE_WIDTH, aThickness);
       
  1545         }
       
  1546     VGPaint paint;
       
  1547     if (aDrawMode != EHuiNoFill)
       
  1548         {
       
  1549         paint = vgGetPaint(VG_FILL_PATH);
       
  1550         }
       
  1551      else
       
  1552         {
       
  1553         paint = vgGetPaint(VG_STROKE_PATH);
       
  1554         }
       
  1555 
       
  1556     VGfloat color[4], modifiedColor[4];
       
  1557     
       
  1558     if (paint != VG_INVALID_HANDLE)
       
  1559        {
       
  1560        vgGetParameterfv(paint, VG_PAINT_COLOR, 4, color);
       
  1561        if (color[3]!=alpha) 
       
  1562            {
       
  1563            modifiedColor[0] = color[0];
       
  1564            modifiedColor[1] = color[1];
       
  1565            modifiedColor[2] = color[2];
       
  1566            modifiedColor[3] = alpha;
       
  1567            vgSetParameterfv(paint, VG_PAINT_COLOR, 4, modifiedColor);
       
  1568            }
       
  1569        else
       
  1570            {
       
  1571            // no reason to set back the old color. it is the same.
       
  1572            paint = VG_INVALID_HANDLE; 
       
  1573            }
       
  1574        }
       
  1575 
       
  1576     UsePaintPattern();
       
  1577     
       
  1578     if (aDrawMode != EHuiNoFill)
       
  1579         {
       
  1580         vgDrawPath(iArcPath, VG_FILL_PATH);
       
  1581         }
       
  1582     else
       
  1583         {
       
  1584         vgDrawPath(iArcPath, VG_STROKE_PATH);
       
  1585         }
       
  1586 
       
  1587     DiscardPaintPattern();
       
  1588     
       
  1589     // Restore old values
       
  1590     if (paint != VG_INVALID_HANDLE)
       
  1591         {
       
  1592         vgSetParameterfv(paint, VG_PAINT_COLOR, 4, color);
       
  1593         HUI_VG_INVARIANT();
       
  1594         }
       
  1595     if(oldThickness != aThickness)
       
  1596         {
       
  1597         vgSeti(VG_STROKE_LINE_WIDTH, oldThickness);
       
  1598         }
       
  1599     HUI_VG_INVARIANT();
       
  1600     
       
  1601     }
       
  1602 
       
  1603 void CHuiVg10Gc::DrawRoundRect(const TRect& aDestinationRect, const THuiRealSize& aSize, THuiFillMode aDrawMode, const TInt aThickness)
       
  1604     {
       
  1605     // Fix given destination rect to be in th middle of openvg pixels
       
  1606     THuiRealRect destinationRect = aDestinationRect;
       
  1607     destinationRect.iTl.iX += 0.5f;
       
  1608     destinationRect.iTl.iY += 0.5f;
       
  1609     destinationRect.iBr.iX -= 0.5f;
       
  1610     destinationRect.iBr.iY -= 0.5f;
       
  1611     
       
  1612     VGfloat alpha = PenAlpha();
       
  1613     vgClearPath(iRoundRectPath, VG_PATH_CAPABILITY_APPEND_TO);
       
  1614     vguRoundRect(iRoundRectPath, destinationRect.iTl.iX, destinationRect.iTl.iY, destinationRect.Width(), destinationRect.Height(), aSize.iWidth, aSize.iHeight);
       
  1615    
       
  1616     UpdateColor();
       
  1617     UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1618     
       
  1619     TInt oldThickness = vgGeti(VG_STROKE_LINE_WIDTH);
       
  1620     if(oldThickness != aThickness)
       
  1621         {
       
  1622         vgSeti(VG_STROKE_LINE_WIDTH, aThickness);
       
  1623         }
       
  1624     VGPaint paint;
       
  1625     if (aDrawMode != EHuiNoFill)
       
  1626         {
       
  1627         paint = vgGetPaint(VG_FILL_PATH);
       
  1628         }
       
  1629      else
       
  1630         {
       
  1631         paint = vgGetPaint(VG_STROKE_PATH);
       
  1632         }
       
  1633 
       
  1634     VGfloat color[4], modifiedColor[4];
       
  1635     
       
  1636     if (paint != VG_INVALID_HANDLE)
       
  1637        {
       
  1638        vgGetParameterfv(paint, VG_PAINT_COLOR, 4, color);
       
  1639        if (color[3]!=alpha)
       
  1640            {
       
  1641            modifiedColor[0] = color[0];
       
  1642            modifiedColor[1] = color[1];
       
  1643            modifiedColor[2] = color[2];
       
  1644            modifiedColor[3] = alpha;
       
  1645            vgSetParameterfv(paint, VG_PAINT_COLOR, 4, modifiedColor);
       
  1646            }
       
  1647        else
       
  1648            {
       
  1649            // no reason to set back the old color. it is the same.
       
  1650            paint = VG_INVALID_HANDLE; 
       
  1651            }
       
  1652        }
       
  1653 
       
  1654     UsePaintPattern();
       
  1655     
       
  1656     if (aDrawMode != EHuiNoFill)
       
  1657         {
       
  1658         vgDrawPath(iRoundRectPath, VG_FILL_PATH);
       
  1659         }
       
  1660     else
       
  1661         {
       
  1662         vgDrawPath(iRoundRectPath, VG_STROKE_PATH);
       
  1663         }
       
  1664 
       
  1665     DiscardPaintPattern();
       
  1666     
       
  1667     if (paint != VG_INVALID_HANDLE)
       
  1668         {
       
  1669         vgSetParameterfv(paint, VG_PAINT_COLOR, 4, color);
       
  1670         HUI_VG_INVARIANT();
       
  1671         }
       
  1672     if(oldThickness != aThickness)
       
  1673         {
       
  1674         vgSeti(VG_STROKE_LINE_WIDTH, oldThickness);
       
  1675         }
       
  1676     HUI_VG_INVARIANT();
       
  1677     }
       
  1678 
       
  1679 void CHuiVg10Gc::DrawBorders(const TRect& aOuterRect, 
       
  1680 				  TReal32 aLeftBorderWidth,
       
  1681                   TReal32 aRightBorderWidth, 
       
  1682 				  TReal32 aTopBorderHeight,
       
  1683                   TReal32 aBottomBorderHeight, 
       
  1684                   TBorderMode aBorderMode,
       
  1685                   const THuiImage* aImage) __SOFTFP
       
  1686 	{	
       
  1687     UpdateColor();
       
  1688     
       
  1689     if (aBorderMode == EBorderImage)
       
  1690         {
       
  1691         TReal32 avgBorderWidth     = (aLeftBorderWidth + aRightBorderWidth) * .5f;
       
  1692         TReal32 avgBorderHeight    = (aTopBorderHeight + aBottomBorderHeight) * .5f;
       
  1693         THuiRealPoint borderOffset = THuiRealPoint((aRightBorderWidth   - aLeftBorderWidth) * .5f,
       
  1694                                                    (aBottomBorderHeight - aTopBorderHeight) * .5f);
       
  1695         DrawBorderImages(aOuterRect, avgBorderWidth, avgBorderHeight, borderOffset, aImage);
       
  1696         }
       
  1697     else if (aBorderMode == EBorderFixedCorners)
       
  1698         {
       
  1699         DrawBorderFixedCorners(aOuterRect, aLeftBorderWidth, aRightBorderWidth, 
       
  1700                                aTopBorderHeight, aBottomBorderHeight, aImage);
       
  1701         }
       
  1702     else
       
  1703         {
       
  1704         // We cannot leave here because we are a non-leaving function,
       
  1705         // and we cannot return an error either. 
       
  1706         // If the caller gives us invalid parameters, we do nothing.
       
  1707         return;
       
  1708         }
       
  1709 
       
  1710     HUI_VG_INVARIANT();
       
  1711 	}
       
  1712 
       
  1713 void CHuiVg10Gc::DrawBorderImages(const TRect& aOuterRect,
       
  1714                                   TReal32 aBorderWidth,
       
  1715                                   TReal32 aBorderHeight, 
       
  1716                                   THuiRealPoint aOffset,
       
  1717                                   const THuiImage* aImage)
       
  1718     {
       
  1719     // If there is no image, draw a solid border
       
  1720     if (!aImage || !aImage->HasTexture())
       
  1721         {
       
  1722         //
       
  1723         // The border is drawn like this:
       
  1724         //
       
  1725         //      +-----------------+
       
  1726         //      |                 |
       
  1727         //      +---+---------+   |
       
  1728         //      |   |         |   |
       
  1729         //      |   |         |   |
       
  1730         //      |   |         |   |
       
  1731         //      |   |         |   |
       
  1732         //      |   +---------+   |
       
  1733         //      |                 |
       
  1734         //      +-----------------+
       
  1735         //
       
  1736         // We do not use a path with a hole, because some of the edges might become too thin.
       
  1737         //
       
  1738         TReal32 w = aOuterRect.Width();
       
  1739         TReal32 h = aOuterRect.Height();
       
  1740 
       
  1741         const VGfloat borderCoords[10 * 2] = 
       
  1742             {
       
  1743             aOuterRect.iTl.iX, aOuterRect.iTl.iY,
       
  1744             w, 0.0f,
       
  1745             0.0f, h,
       
  1746             -w, 0.0f,
       
  1747             0.0f, -h + aBorderWidth,
       
  1748             aBorderWidth, 0.0f,
       
  1749             0.0f, h - aBorderHeight - aBorderHeight,
       
  1750             w - aBorderHeight - aBorderHeight, 0.0f,
       
  1751             0.0f, -h + aBorderHeight + aBorderHeight,
       
  1752             -w + aBorderWidth, 0.0f,
       
  1753             };
       
  1754 
       
  1755         UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1756         vgModifyPathCoords(iBorderPath, 0, 12, borderCoords);
       
  1757         vgDrawPath(iBorderPath, VG_FILL_PATH);
       
  1758         
       
  1759         HUI_VG_INVARIANT();
       
  1760         return;
       
  1761         }
       
  1762     
       
  1763     THuiRealRect texCoords = GetSourceRectangleFromImage(*aImage);
       
  1764     THuiRealPoint midTexCoord((texCoords.iTl.iX + texCoords.iBr.iX) * .5f,
       
  1765                               (texCoords.iTl.iY + texCoords.iBr.iY) * .5f);
       
  1766 
       
  1767     THuiRealRect outerRect(aOuterRect);
       
  1768     outerRect.iTl += aOffset;
       
  1769     outerRect.iBr += aOffset;
       
  1770     THuiRealRect innerRect(aOuterRect);
       
  1771     innerRect.Shrink(aBorderWidth, aBorderHeight);
       
  1772 
       
  1773     // Top left segment
       
  1774     DrawCroppedTexture(aImage->Texture(), 
       
  1775                        THuiRealRect(texCoords.iTl, midTexCoord), 
       
  1776                        THuiRealRect(outerRect.iTl, innerRect.iTl));
       
  1777 
       
  1778     // Top segment
       
  1779     DrawCroppedTexture(aImage->Texture(), 
       
  1780                        THuiRealRect(THuiRealPoint(midTexCoord.iX, texCoords.iTl.iY), midTexCoord),
       
  1781                        THuiRealRect(THuiRealPoint(innerRect.iTl.iX, outerRect.iTl.iY), innerRect.TopRight()));
       
  1782 
       
  1783     // Top right segment
       
  1784     DrawCroppedTexture(aImage->Texture(), 
       
  1785                        THuiRealRect(THuiRealPoint(midTexCoord.iX, texCoords.iTl.iY),
       
  1786                                     THuiRealPoint(texCoords.iBr.iX, midTexCoord.iY)),
       
  1787                        THuiRealRect(THuiRealPoint(innerRect.iBr.iX, outerRect.iTl.iY),
       
  1788                                     THuiRealPoint(outerRect.iBr.iX, innerRect.iTl.iY)));
       
  1789 
       
  1790     // Right segment
       
  1791     DrawCroppedTexture(aImage->Texture(), 
       
  1792                        THuiRealRect(midTexCoord, 
       
  1793                                     THuiRealPoint(texCoords.iBr.iX, midTexCoord.iY)),
       
  1794                        THuiRealRect(innerRect.TopRight(),
       
  1795                                     THuiRealPoint(outerRect.iBr.iX, innerRect.iBr.iY)));
       
  1796 
       
  1797     // Bottom right segment
       
  1798     DrawCroppedTexture(aImage->Texture(), 
       
  1799                        THuiRealRect(midTexCoord, texCoords.iBr),
       
  1800                        THuiRealRect(innerRect.iBr, outerRect.iBr));
       
  1801 
       
  1802     // Bottom segment
       
  1803     DrawCroppedTexture(aImage->Texture(), 
       
  1804                        THuiRealRect(midTexCoord, 
       
  1805                                     THuiRealPoint(midTexCoord.iX, texCoords.iBr.iY)),
       
  1806                        THuiRealRect(innerRect.BottomLeft(),
       
  1807                                     THuiRealPoint(innerRect.iBr.iX, outerRect.iBr.iY)));
       
  1808 
       
  1809     // Bottom left segment
       
  1810     DrawCroppedTexture(aImage->Texture(), 
       
  1811                        THuiRealRect(THuiRealPoint(texCoords.iTl.iX, midTexCoord.iY),
       
  1812                                     THuiRealPoint(midTexCoord.iX, texCoords.iBr.iY)),
       
  1813                        THuiRealRect(THuiRealPoint(outerRect.iTl.iX, innerRect.iBr.iY),
       
  1814                                     THuiRealPoint(innerRect.iTl.iX, outerRect.iBr.iY)));
       
  1815 
       
  1816     // Left segment
       
  1817     DrawCroppedTexture(aImage->Texture(), 
       
  1818                        THuiRealRect(THuiRealPoint(texCoords.iTl.iX, midTexCoord.iY), 
       
  1819                                     midTexCoord),
       
  1820                        THuiRealRect(THuiRealPoint(outerRect.iTl.iX, innerRect.iTl.iY),
       
  1821                                     innerRect.BottomLeft()));
       
  1822     HUI_VG_INVARIANT();
       
  1823     }
       
  1824 
       
  1825 void CHuiVg10Gc::DrawBorderFixedCorners(const TRect& aOuterRect, 
       
  1826                                         TReal32 aLeftBorderWidth,
       
  1827                                         TReal32 aRightBorderWidth, 
       
  1828                                         TReal32 aTopBorderHeight,
       
  1829                                         TReal32 aBottomBorderHeight, 
       
  1830                                         const THuiImage* aImage)
       
  1831     {
       
  1832     // If there is no image, draw a solid border
       
  1833     if (!aImage || !aImage->HasTexture())
       
  1834         {
       
  1835         //
       
  1836         // The border is drawn like this:
       
  1837         //
       
  1838         //      +-----------------+
       
  1839         //      |                 |
       
  1840         //      +---+---------+   |
       
  1841         //      |   |         |   |
       
  1842         //      |   |         |   |
       
  1843         //      |   |         |   |
       
  1844         //      |   |         |   |
       
  1845         //      |   +---------+   |
       
  1846         //      |                 |
       
  1847         //      +-----------------+
       
  1848         //
       
  1849         // We do not use a path with a hole, because some of the edges might become too thin.
       
  1850         //
       
  1851         TReal32 w = aOuterRect.Width();
       
  1852         TReal32 h = aOuterRect.Height();
       
  1853 
       
  1854         const VGfloat borderCoords[10 * 2] = 
       
  1855             {
       
  1856             aOuterRect.iTl.iX, aOuterRect.iTl.iY,
       
  1857             w, 0.0f,
       
  1858             0.0f, h,
       
  1859             -w, 0.0f,
       
  1860             0.0f, -h + aTopBorderHeight,
       
  1861             aLeftBorderWidth, 0.0f,
       
  1862             0.0f, h - aTopBorderHeight - aBottomBorderHeight,
       
  1863             w - aLeftBorderWidth - aRightBorderWidth, 0.0f,
       
  1864             0.0f, -h + aTopBorderHeight + aBottomBorderHeight,
       
  1865             -w + aRightBorderWidth, 0.0f,
       
  1866             };
       
  1867 
       
  1868         UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1869         vgModifyPathCoords(iBorderPath, 0, 12, borderCoords);
       
  1870         vgDrawPath(iBorderPath, VG_FILL_PATH);
       
  1871         
       
  1872         HUI_VG_INVARIANT();
       
  1873         return;
       
  1874         }
       
  1875     
       
  1876     THuiRealRect texCoords = GetSourceRectangleFromImage(*aImage);
       
  1877     THuiRealRect innerTexCoords(texCoords);
       
  1878     THuiRealSize texSize = aImage->Texture().Size();
       
  1879     THuiRealRect outerRect(aOuterRect);
       
  1880     THuiRealRect innerRect(aOuterRect);
       
  1881     
       
  1882     innerTexCoords.iTl.iX += aLeftBorderWidth    / texSize.iWidth;
       
  1883     innerTexCoords.iTl.iY += aTopBorderHeight    / texSize.iHeight;
       
  1884     innerTexCoords.iBr.iX -= aRightBorderWidth   / texSize.iWidth;
       
  1885     innerTexCoords.iBr.iY -= aBottomBorderHeight / texSize.iHeight;
       
  1886 
       
  1887     innerRect.iTl.iX += aLeftBorderWidth;
       
  1888     innerRect.iTl.iY += aTopBorderHeight;
       
  1889     innerRect.iBr.iX -= aRightBorderWidth;
       
  1890     innerRect.iBr.iY -= aBottomBorderHeight;
       
  1891 
       
  1892     // Top left segment
       
  1893     if (aTopBorderHeight > 0.0f && aLeftBorderWidth > 0.0f)
       
  1894         {
       
  1895         DrawCroppedTexture(aImage->Texture(), 
       
  1896                          THuiRealRect(texCoords.iTl, innerTexCoords.iTl), 
       
  1897                          THuiRealRect(outerRect.iTl, innerRect.iTl));
       
  1898         }
       
  1899 
       
  1900     // Top segment
       
  1901     if (aTopBorderHeight > 0.0f)
       
  1902         {
       
  1903         DrawCroppedTexture(aImage->Texture(), 
       
  1904                            THuiRealRect(THuiRealPoint(innerTexCoords.iTl.iX, texCoords.iTl.iY), 
       
  1905                                         innerTexCoords.TopRight()),
       
  1906                            THuiRealRect(THuiRealPoint(innerRect.iTl.iX, outerRect.iTl.iY), 
       
  1907                                         innerRect.TopRight()));
       
  1908         }
       
  1909 
       
  1910     // Top right segment
       
  1911     if (aTopBorderHeight > 0.0f && aRightBorderWidth > 0.0f)
       
  1912         {
       
  1913         DrawCroppedTexture(aImage->Texture(), 
       
  1914                            THuiRealRect(THuiRealPoint(innerTexCoords.iBr.iX, texCoords.iTl.iY),
       
  1915                                         THuiRealPoint(texCoords.iBr.iX, innerTexCoords.iTl.iY)),
       
  1916                            THuiRealRect(THuiRealPoint(innerRect.iBr.iX, outerRect.iTl.iY),
       
  1917                                         THuiRealPoint(outerRect.iBr.iX, innerRect.iTl.iY)));
       
  1918         }
       
  1919 
       
  1920     // Right segment
       
  1921     if (aRightBorderWidth > 0.0f)
       
  1922         {
       
  1923         DrawCroppedTexture(aImage->Texture(), 
       
  1924                            THuiRealRect(innerTexCoords.TopRight(), 
       
  1925                                         THuiRealPoint(texCoords.iBr.iX, innerTexCoords.iBr.iY)),
       
  1926                            THuiRealRect(innerRect.TopRight(),
       
  1927                                         THuiRealPoint(outerRect.iBr.iX, innerRect.iBr.iY)));
       
  1928         }
       
  1929 
       
  1930     // Bottom right segment
       
  1931     if (aBottomBorderHeight > 0.0f && aRightBorderWidth > 0.0f)
       
  1932         {
       
  1933         DrawCroppedTexture(aImage->Texture(), 
       
  1934                            THuiRealRect(innerTexCoords.iBr, texCoords.iBr),
       
  1935                            THuiRealRect(innerRect.iBr, outerRect.iBr));
       
  1936         }
       
  1937 
       
  1938     // Bottom segment
       
  1939     if (aRightBorderWidth > 0.0f)
       
  1940         {
       
  1941         DrawCroppedTexture(aImage->Texture(), 
       
  1942                            THuiRealRect(innerTexCoords.BottomLeft(),
       
  1943                                         THuiRealPoint(innerTexCoords.iBr.iX, texCoords.iBr.iY)),
       
  1944                            THuiRealRect(innerRect.BottomLeft(),
       
  1945                                         THuiRealPoint(innerRect.iBr.iX, outerRect.iBr.iY)));
       
  1946         }
       
  1947 
       
  1948     // Bottom left segment
       
  1949     if (aBottomBorderHeight > 0.0f && aRightBorderWidth > 0.0f)
       
  1950         {
       
  1951         DrawCroppedTexture(aImage->Texture(), 
       
  1952                            THuiRealRect(THuiRealPoint(texCoords.iTl.iX, innerTexCoords.iBr.iY),
       
  1953                                         THuiRealPoint(innerTexCoords.iTl.iX, texCoords.iBr.iY)),
       
  1954                            THuiRealRect(THuiRealPoint(outerRect.iTl.iX, innerRect.iBr.iY),
       
  1955                                         THuiRealPoint(innerRect.iTl.iX, outerRect.iBr.iY)));
       
  1956         }
       
  1957 
       
  1958     // Left segment
       
  1959     if (aLeftBorderWidth > 0.0f)
       
  1960         {
       
  1961         DrawCroppedTexture(aImage->Texture(), 
       
  1962                            THuiRealRect(THuiRealPoint(texCoords.iTl.iX, innerTexCoords.iTl.iY), 
       
  1963                                         innerTexCoords.BottomLeft()),
       
  1964                            THuiRealRect(THuiRealPoint(outerRect.iTl.iX, innerRect.iTl.iY),
       
  1965                                         innerRect.BottomLeft()));
       
  1966         }
       
  1967     HUI_VG_INVARIANT();
       
  1968     }
       
  1969 
       
  1970 void CHuiVg10Gc::DrawPath(const CHuiCurvePath& aPath,
       
  1971                             const TPoint& aOrigin,
       
  1972                             TReal32 aStartPos,
       
  1973                             TReal32 aEndPos,
       
  1974                             MHuiMappingFunction* aAlphaFunction,
       
  1975                             MHuiMappingFunction* aWidthFunction) __SOFTFP
       
  1976     {
       
  1977     // Refresh the vertices.
       
  1978     CHuiCurvePath* nonConstCurvePath = const_cast<CHuiCurvePath*>(&aPath);
       
  1979     nonConstCurvePath->Update(aStartPos, aEndPos, PenAlpha() / 255.f,
       
  1980                               aAlphaFunction, aWidthFunction);
       
  1981 
       
  1982     aPath.Draw(aOrigin, this);
       
  1983     HUI_VG_INVARIANT();
       
  1984     }
       
  1985 
       
  1986 
       
  1987 void CHuiVg10Gc::DrawMesh(const CHuiMesh& /*aMesh*/, const THuiImage* /*aImage*/,
       
  1988                             const THuiImage* /*aSecondaryImage*/,
       
  1989                             TReal32 /*aSecondaryAlpha*/) __SOFTFP
       
  1990     {
       
  1991     HUI_DEBUGF(_L("CHuiVg10Gc::DrawMesh() - Method has not been implemented! Sorry."));     
       
  1992     }
       
  1993 
       
  1994 void CHuiVg10Gc::DrawArc(const TPoint& /*aOrigin*/, const TSize& /*aRadius*/,
       
  1995                            TReal32 /*aEnd*/, TReal32 /*aStart*/, TInt /*aAnglePerSegment*/,
       
  1996                            TReal32 /*aWidth*/, const THuiImage& /*aImage*/,
       
  1997                            TReal32 (aAlphaFunc)(TReal32), TBool /*aAbsoluteAngleParm*/) __SOFTFP
       
  1998     {
       
  1999 	 // not supported
       
  2000 	aAlphaFunc(1.0); // just to disable compiler warning
       
  2001     return;
       
  2002     }
       
  2003 
       
  2004 
       
  2005 
       
  2006 void CHuiVg10Gc::DrawGradient(TGradientType aType, const TRect& aRect,
       
  2007                               const TRgb& aStartColor, const TRgb& aEndColor,
       
  2008                               TReal32 aStartOpacity, TReal32 aEndOpacity,
       
  2009                               const THuiRealRect* aTexCoords) __SOFTFP
       
  2010     {
       
  2011     VGfloat gradientCoords[4];
       
  2012     VGfloat x1 = (VGfloat)aRect.iTl.iX;
       
  2013     VGfloat y1 = (VGfloat)aRect.iTl.iY;
       
  2014     VGfloat x2 = (VGfloat)aRect.iBr.iX;
       
  2015     VGfloat y2 = (VGfloat)aRect.iBr.iY;
       
  2016     
       
  2017     switch (aType)
       
  2018         {
       
  2019         case EGradientLinearUp:
       
  2020             gradientCoords[0] = x1;  gradientCoords[1] = y2;
       
  2021             gradientCoords[2] = x1;  gradientCoords[3] = y1;
       
  2022             break;
       
  2023         case EGradientLinearRight:
       
  2024             gradientCoords[0] = x1;  gradientCoords[1] = y1;
       
  2025             gradientCoords[2] = x2;  gradientCoords[3] = y1;
       
  2026             break;
       
  2027         case EGradientLinearDown:
       
  2028             gradientCoords[0] = x1;  gradientCoords[1] = y1;
       
  2029             gradientCoords[2] = x1;  gradientCoords[3] = y2;
       
  2030             break;
       
  2031         case EGradientLinearLeft:
       
  2032             gradientCoords[0] = x2;  gradientCoords[1] = y1;
       
  2033             gradientCoords[2] = x1;  gradientCoords[3] = y1;
       
  2034             break;
       
  2035         }
       
  2036 
       
  2037     VGfloat scale = 1.0f / 255.0f;
       
  2038     const VGfloat gradientStops[] =
       
  2039         {
       
  2040         0.0f,  aStartColor.Red() * scale, aStartColor.Green() * scale, aStartColor.Blue() * scale, aStartOpacity,
       
  2041         1.0f,  aEndColor.Red()   * scale, aEndColor.Green()   * scale, aEndColor.Blue()   * scale, aEndOpacity,
       
  2042         };
       
  2043     
       
  2044     vgSetParameterfv(iGradientPaint, VG_PAINT_LINEAR_GRADIENT, 2 * 2, gradientCoords);
       
  2045     vgSetParameterfv(iGradientPaint, VG_PAINT_COLOR_RAMP_STOPS, 2 * 5, gradientStops);
       
  2046     vgSetPaint(iGradientPaint, VG_FILL_PATH);
       
  2047     HUI_VG_INVARIANT();
       
  2048 
       
  2049     UpdateColor();
       
  2050     UpdateMatrix(VG_MATRIX_PATH_USER_TO_SURFACE);
       
  2051     
       
  2052     // Draw the gradient as an image if we have a texture, otherwise draw a regular rectangle
       
  2053     if (aTexCoords)
       
  2054         {
       
  2055         /*
       
  2056         CHuiDisplay* display = CHuiStatic::Env().CurrentDisplay();
       
  2057 
       
  2058         if (!display)
       
  2059             {
       
  2060             THuiPanic::Panic(THuiPanic::EVg10Invariant);
       
  2061             }
       
  2062         CHuiVg10RenderSurface* surface = static_cast<CHuiVg10RenderSurface*>(&display->RenderSurface());
       
  2063 		*/
       
  2064 		
       
  2065         CHuiVg10RenderSurface* surface = static_cast<CHuiVg10RenderSurface*>(CHuiStatic::CurrentRenderSurface());
       
  2066 
       
  2067         if (!surface)
       
  2068             {
       
  2069             THuiPanic::Panic(THuiPanic::EVg10Invariant);
       
  2070             }
       
  2071         
       
  2072         const MHuiSegmentedTexture* tex = surface->BoundTexture();
       
  2073 
       
  2074         if (!tex)
       
  2075             {
       
  2076             DrawRect(aRect);
       
  2077             }
       
  2078         else
       
  2079             {
       
  2080             vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY); // Will be restored by next call to UpdateColor()
       
  2081             DrawTexture(*tex, *aTexCoords, aRect);
       
  2082             }
       
  2083         }
       
  2084     else
       
  2085         {
       
  2086         DrawRect(aRect);
       
  2087         }
       
  2088     HUI_VG_INVARIANT();
       
  2089     
       
  2090     // Restore the original paint
       
  2091     vgSetPaint(iPaint, VG_FILL_PATH | VG_STROKE_PATH);
       
  2092     UpdateColor();
       
  2093     }
       
  2094 
       
  2095 
       
  2096 void CHuiVg10Gc::SetDepthOffset(TInt /*aOffset*/)
       
  2097     {
       
  2098     // No depth offset on OpenVG
       
  2099     }
       
  2100 
       
  2101 
       
  2102 TUint8* CHuiVg10Gc::CaptureLC(TSize& aSize) const
       
  2103     {
       
  2104     TRect displayArea = RawDisplayArea();
       
  2105 
       
  2106     TUint8* buffer = new (ELeave) TUint8[displayArea.Width() *
       
  2107                                          displayArea.Height() * 4];
       
  2108     CleanupStack::PushL(buffer);
       
  2109 
       
  2110     aSize = displayArea.Size();
       
  2111     vgReadPixels(buffer, displayArea.Width() * 4, VG_lARGB_8888, 0, 0, 
       
  2112                  displayArea.Width(), displayArea.Height());
       
  2113 
       
  2114     return buffer;
       
  2115     }
       
  2116 
       
  2117 #ifdef __NVG
       
  2118 void CHuiVg10Gc::DrawNVG(HBufC8* aNVGData, MNVGIcon* aIconCmds, const TSize& aImageSize, TBool aIgnoreAspectRatio)
       
  2119     {
       
  2120     HUI_VG_INVARIANT();
       
  2121     
       
  2122     if (!aNVGData)
       
  2123         return;
       
  2124     // Parse the icon header info from the extended data
       
  2125     TPtr8 IconHeaderPtr((TUint8 *)aNVGData->Des().Ptr(), KIconHeaderLength, KIconHeaderLength);
       
  2126     TAknIconHeader iconheader(IconHeaderPtr);
       
  2127 
       
  2128     // The rest of the data (after the iconheader) are the OVG drawing instructions
       
  2129     TInt lengthAfterHeader = aNVGData->Length() - KIconHeaderLength;
       
  2130     TPtr8 nvgDataVoidIC((TUint8 *)aNVGData->Des().Ptr() + KIconHeaderLength, lengthAfterHeader, lengthAfterHeader);
       
  2131     
       
  2132     // Set the rotation angle
       
  2133     iNvgEngine->Rotate(iconheader.GetRotation(), aImageSize.iWidth >>1, aImageSize.iHeight >>1);
       
  2134     
       
  2135     if (aIgnoreAspectRatio == EFalse)
       
  2136     {
       
  2137         // Set preserve aspect ratio (if not ignored)
       
  2138         TNvgAlignStatusType alignTypeValue = ENvgPreserveAspectRatio_XmidYmid;
       
  2139         TNvgMeetOrSliceType meetOrSliceTypeValue = ENvgMeet;
       
  2140         
       
  2141         switch ( iconheader.GetScaleMode() )
       
  2142             {
       
  2143             case EAspectRatioPreserved:
       
  2144                 {
       
  2145                 // Use default
       
  2146                 break;
       
  2147                 }
       
  2148             // Ensures NVG content fully covers the area
       
  2149             // of the icon whilst preserving aspect ratio.
       
  2150             case EAspectRatioPreservedSlice:
       
  2151                 {
       
  2152                 // alignTypeValue use default
       
  2153                 meetOrSliceTypeValue = ENvgSlice;
       
  2154                 break;
       
  2155                 }
       
  2156             // EAspectRatioPreservedAndUnusedSpaceRemoved is mapped to the same
       
  2157             // values as EAspectRatioNotPreserved because we already have a
       
  2158             // frame buffer with the dimensions that preserves the aspect ratio.
       
  2159             // This mapping ensures that NVG engine does not calculate aspect
       
  2160             // ratio twice and potentially resulting in precision loss.
       
  2161             case EAspectRatioPreservedAndUnusedSpaceRemoved:
       
  2162             case EAspectRatioNotPreserved:
       
  2163                 {            
       
  2164                 alignTypeValue = ENvgPreserveAspectRatio_None;
       
  2165                 // meetOrSliceTypeValue use default
       
  2166                 break;
       
  2167                 }
       
  2168             }
       
  2169         iNvgEngine->SetPreserveAspectRatio(alignTypeValue, meetOrSliceTypeValue);
       
  2170     }
       
  2171     
       
  2172     // Draw the NVG path onto the current surface using the NVGEngine
       
  2173     if (aIconCmds)
       
  2174         {
       
  2175         aIconCmds->Draw(aImageSize, iNvgEngine);
       
  2176         }
       
  2177     else
       
  2178         {
       
  2179         // Fall back drawing directly from the nvg data
       
  2180         HUI_DEBUG(_L("CHuiVg10Gc::DrawNVG() - Fallback to draw the old way (via DrawNvg)"));
       
  2181         iNvgEngine->DrawNvg(nvgDataVoidIC, aImageSize, NULL, NULL);
       
  2182         }
       
  2183 
       
  2184 #ifdef _DEBUG
       
  2185     // TODO: REMOVE ONCE THE TSW ERROR IS FIXED!
       
  2186     VGErrorCode err = vgGetError();
       
  2187     if (err)
       
  2188         {
       
  2189         RDebug::Print(_L("CHuiVg10Gc::DrawNVG - Error in NVG draw: %04x"), err);
       
  2190         }
       
  2191 #endif
       
  2192     
       
  2193     // The NVG draw messes up the paint, scissoring & rects, so mark them as dirty
       
  2194     TInt dirtyFlags = EHuiVg10GcStateFlagDirtyPaint |
       
  2195                     EHuiVg10GcStateFlagDirtyScissor | 
       
  2196                     EHuiVg10GcStateFlagDirtyScissorRects;
       
  2197     ((CHuiVg10RenderPlugin&)CHuiStatic::Renderer()).AddRestoreStateFlags(dirtyFlags);
       
  2198     // Restore the paint etc.
       
  2199     RestoreFlaggedState();
       
  2200 
       
  2201     HUI_VG_INVARIANT();
       
  2202     }
       
  2203 #endif
       
  2204 
       
  2205 void CHuiVg10Gc::TransformDirtyRect(THuiRealRect& aRect)
       
  2206     {
       
  2207     THuiRealRect transformed = aRect;
       
  2208     
       
  2209     // Transform the rectangle using our stacks
       
  2210     UpdateClientMatrix();
       
  2211     iMatrixStack->Current().Multiply(transformed.iTl);
       
  2212     iMatrixStack->Current().Multiply(transformed.iBr);
       
  2213     
       
  2214     // Normalize the rectangle
       
  2215     if (transformed.iTl.iX > transformed.iBr.iX)
       
  2216         {
       
  2217         TReal32 tmp = transformed.iTl.iX;
       
  2218         transformed.iTl.iX = transformed.iBr.iX;
       
  2219         transformed.iBr.iX = tmp;
       
  2220         }
       
  2221     if (transformed.iTl.iY > transformed.iBr.iY)
       
  2222         {
       
  2223         TReal32 tmp = transformed.iTl.iY;
       
  2224         transformed.iTl.iY = transformed.iBr.iY;
       
  2225         transformed.iBr.iY = tmp;
       
  2226         }    
       
  2227 
       
  2228     aRect = transformed;
       
  2229     }
       
  2230 
       
  2231 void CHuiVg10Gc::SetPaintPattern(CHuiTexture* aTexture, const TPoint& aTextureOrigin)
       
  2232     {
       
  2233     if (aTexture)
       
  2234         {
       
  2235         // TODO: This does not work if texture has NVG data only
       
  2236         iPaintPattern = GetVGImageFromTexture( *aTexture );
       
  2237         }
       
  2238     else
       
  2239         {
       
  2240         iPaintPattern = VG_INVALID_HANDLE;
       
  2241         }
       
  2242 
       
  2243     if (iPaintPattern)
       
  2244         {
       
  2245         vgSetParameteri(iPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_PATTERN);
       
  2246         vgSetParameteri(iPaint, VG_PAINT_PATTERN_TILING_MODE, VG_TILE_REPEAT);        
       
  2247         iPaintPatternOrigin = aTextureOrigin;
       
  2248         }
       
  2249     else
       
  2250         {
       
  2251         vgSetParameteri(iPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
       
  2252         vgSetParameteri(iPaint, VG_PAINT_PATTERN_TILING_MODE, VG_TILE_FILL);        
       
  2253         iPaintPatternOrigin = TPoint(0,0);
       
  2254         }
       
  2255     
       
  2256     vgPaintPattern(iPaint, iPaintPattern);
       
  2257     }
       
  2258 
       
  2259 void CHuiVg10Gc::UsePaintPattern()
       
  2260     {
       
  2261     if (iPaintPattern)
       
  2262         {
       
  2263         // Transform the paint pattern to fill the destination rectangle as required
       
  2264         vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
  2265         vgLoadIdentity();
       
  2266         vgTranslate(iPaintPatternOrigin.iX, iPaintPatternOrigin.iY);
       
  2267         vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  2268         }
       
  2269     }
       
  2270 
       
  2271 void CHuiVg10Gc::DiscardPaintPattern()
       
  2272     {
       
  2273     if (iPaintPattern)
       
  2274         {
       
  2275         // Restore
       
  2276         vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
  2277         vgLoadIdentity();
       
  2278         vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  2279         }
       
  2280     }
       
  2281 
       
  2282 
       
  2283 // End of file
       
  2284