svgtopt/nvgdecoder/src/nvg.cpp
changeset 46 88edb906c587
equal deleted inserted replaced
-1:000000000000 46:88edb906c587
       
     1 /*
       
     2 * Copyright (c) 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:  NVG Decoder source file
       
    15 *
       
    16 */
       
    17 
       
    18  
       
    19 #include <s32mem.h>
       
    20 #include <libc/math.h> 
       
    21 #include <e32math.h>
       
    22 
       
    23 #include "nvg.h"
       
    24 #include "nvgfittoviewbox.h"
       
    25 #include "NVGUtil.h"
       
    26 
       
    27 #include "NVGCSIcon.h"
       
    28 #include "NVGTLVIcon.h"
       
    29 #include "FloatFixPt.h"
       
    30 
       
    31 #include "NVGIconData.h"
       
    32 
       
    33 /*
       
    34  * may be we should use dynamic_cast?
       
    35  */
       
    36 #define CSICON(icon)      ((CNVGCSIcon *)icon) 
       
    37 #define TLVICON(icon)     ((CNVGTLVIcon *)icon) 
       
    38 
       
    39 enum TNVGFormats
       
    40     {
       
    41     ENVGCS,
       
    42     ENVGTLV
       
    43     };
       
    44 
       
    45 /*
       
    46  *  NVG-CS version
       
    47  */
       
    48 //const TInt KVersion1   = 1;
       
    49 const TInt KVersion2   = 2;
       
    50 
       
    51 /*
       
    52  * constants for nvg file header offsets
       
    53  */ 
       
    54 const TUint8 KNVG_SIGNATURE[]       = "nvg";
       
    55 const TInt KNVG_SIGNATURE_LENGTH    = sizeof(KNVG_SIGNATURE) - sizeof('\0');
       
    56 const TInt KNVG_COMMANDSECTION_OFS  = 2;
       
    57 const TInt KNVG_VERSION_OFS         = 3;
       
    58 const TInt KNVG_RGBA_OFS            = 4;
       
    59 const TInt KNVG_HEADERSIZE_OFS      = 4;
       
    60 const TInt KNVG_PATHDATATYPE_OFS    = 26;
       
    61 const TInt KNVG_SCALE_OFS           = 28;
       
    62 const TInt KNVG_BIAS_OFS            = 32;
       
    63 const TInt KNVG_VIEWBOX_X_OFS       = 36;
       
    64 const TInt KNVG_VIEWBOX_Y_OFS       = 40;
       
    65 const TInt KNVG_VIEWBOX_WIDTH_OFS   = 44;
       
    66 const TInt KNVG_VIEWBOX_HEIGHT_OFS  = 48;
       
    67 
       
    68 const TInt KNVG_PAINTSECTION_LINEARGRAD_TRANSFORM_OFFSET = 20;
       
    69 const TInt KNVG_PAINTSECTION_RADIALGRAD_TRANSFORM_OFFSET = 24;
       
    70 
       
    71 /*
       
    72  * nvg-cs commands
       
    73  */ 
       
    74 const TInt KCMD_SET_FILL_PAINT           = 4  << 24;
       
    75 const TInt KCMD_SET_COLOR_RAMP           = 6  << 24;
       
    76 const TInt KCMD_DRAW_PATH                = 7  << 24;
       
    77 const TInt KCMD_SET_TRANSFORMATION       = 8  << 24;
       
    78 const TInt KCMD_SET_STROKE_PAINT         = 5  << 24;
       
    79 const TInt KCMD_SET_STROKE_WIDTH         = 9  << 24;
       
    80 const TInt KCMD_SET_STROKE_LINE_JOIN_CAP = 10 << 24;
       
    81 const TInt KCMD_SET_STROKE_MITER_LIMIT   = 11 << 24;
       
    82 
       
    83 /*
       
    84  * stroke cap style
       
    85  */
       
    86 const TInt KCAP_BUTT        = 1;
       
    87 const TInt KCAP_SQUARE      = 2;
       
    88 const TInt KCAP_ROUND       = 3;
       
    89 
       
    90 /*
       
    91  * stroke join style
       
    92  */
       
    93 const TInt KLINE_JOIN_BEVEL = 1;
       
    94 const TInt KLINE_JOIN_MITER = 2;
       
    95 const TInt KLINE_JOIN_ROUND = 3;
       
    96 
       
    97 /*
       
    98  * fill paint type
       
    99  */
       
   100 const TInt KPAINT_FLAT      = 1;
       
   101 const TInt KPAINT_LGRAD     = 2;
       
   102 const TInt KPAINT_RGRAD     = 3;
       
   103 
       
   104 /*
       
   105  * stroke paint type
       
   106  */
       
   107 const TInt KSTROKE_LGRAD        = 2;
       
   108 const TInt KSTROKE_RGRAD        = 3;
       
   109 const TInt KSTROKE_COLOR_RAMP   = 4;
       
   110 
       
   111 /*
       
   112  * nvg offset
       
   113  */
       
   114 const TInt KOffsetReserved1       = 6;
       
   115 
       
   116 /*
       
   117  * transform encoding values
       
   118  */
       
   119 const TInt KTRANSFORM_COMPLETE    = 0;
       
   120 const TInt KTRANSFORM_SCALING     = 2;
       
   121 const TInt KTRANSFORM_SHEARING    = 4;
       
   122 const TInt KTRANSFORM_ROTATION    = 8;
       
   123 const TInt KTRANSFORM_TRANSLATION = 16;
       
   124 
       
   125 #ifdef OPENVG_OBJECT_CACHING
       
   126 const VGfloat KIdentityMatrix[] = 
       
   127     {
       
   128     1.0f, 0.0f, 0.0f,
       
   129     0.0f, 1.0f, 0.0f,
       
   130     0.0f, 0.0f ,1.0f
       
   131     };
       
   132 #endif
       
   133 
       
   134 /*
       
   135  * function to delete array, for basic types
       
   136  */
       
   137 GLDEF_C void CleanupArray( TAny * aObj )
       
   138     {
       
   139     delete [] aObj;
       
   140     }
       
   141 
       
   142 /*
       
   143  * function to delete array of TFloatFixArray
       
   144  */
       
   145 GLDEF_C void CleanupTFloatFixArray( TAny * aObj )
       
   146     {
       
   147     TFloatFixPt * ff = (TFloatFixPt *)aObj;
       
   148     delete [] ff;
       
   149     }
       
   150 
       
   151 /**
       
   152  * @class   TNVGEngineInternal
       
   153  * This class is added to maintain BC.
       
   154  * If you want to add new member variable you can add in this class, without breaking BC.
       
   155  * It is better to add members which are depend on macro's in this class.
       
   156  */
       
   157 class TNVGEngineInternal
       
   158     {
       
   159 public:
       
   160     TNVGEngineInternal()
       
   161         {
       
   162 #ifdef    OPENVG_OBJECT_CACHING
       
   163         iCreatingNVGIcon = 0;
       
   164         iCurrentNVGIcon  = 0;
       
   165 #endif
       
   166         }
       
   167     
       
   168 #ifdef    OPENVG_OBJECT_CACHING
       
   169     TInt        iCreatingNVGIcon;
       
   170     MNVGIcon *  iCurrentNVGIcon;
       
   171 #endif
       
   172     };
       
   173 
       
   174 CNvgEngine::CNvgEngine()
       
   175     : iCurrentBufferSize(1, 1),
       
   176       iPath(VG_INVALID_HANDLE),
       
   177       iPaintFill(VG_INVALID_HANDLE),
       
   178       iPaintStroke( VG_INVALID_HANDLE),
       
   179       iUserStrokePaintColor(0xFFFFFFFF),
       
   180       iRotateApplied(EFalse),
       
   181       iLastPathDataType(0),
       
   182       iPreserveAspectSetting(ENvgPreserveAspectRatio_XmidYmid),
       
   183       iSmilFitSetting(ENvgMeet),
       
   184       iVGImageBinder(0)
       
   185     {
       
   186     }
       
   187 
       
   188 EXPORT_C CNvgEngine* CNvgEngine::NewL()
       
   189     {
       
   190     CNvgEngine* self    = new (ELeave) CNvgEngine;
       
   191     CleanupStack::PushL(self);
       
   192     self->ConstructL();
       
   193     CleanupStack::Pop(self);
       
   194     return self;
       
   195     }
       
   196 
       
   197 void CNvgEngine::ConstructL()
       
   198     {
       
   199     vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_BETTER);
       
   200     vgSeti(VG_FILL_RULE, VG_NON_ZERO);
       
   201     
       
   202     iInternal = new (ELeave) TNVGEngineInternal;
       
   203     iPaintFill = vgCreatePaint();
       
   204     }
       
   205 
       
   206 EXPORT_C CNvgEngine::~CNvgEngine()
       
   207     {
       
   208     if (iPath != VG_INVALID_HANDLE)
       
   209         {
       
   210         vgDestroyPath(iPath);
       
   211         }
       
   212     
       
   213     if (iPaintFill != VG_INVALID_HANDLE)
       
   214         {
       
   215         vgSetPaint(VG_INVALID_HANDLE, VG_FILL_PATH);
       
   216         vgDestroyPaint(iPaintFill);
       
   217         }
       
   218 		
       
   219     if (iPaintStroke != VG_INVALID_HANDLE)
       
   220         {
       
   221         vgSetPaint(VG_INVALID_HANDLE, VG_STROKE_PATH);
       
   222         vgDestroyPaint(iPaintStroke);
       
   223         }
       
   224 
       
   225     
       
   226 #ifdef    OPENVG_OBJECT_CACHING
       
   227     if (iInternal)
       
   228         {
       
   229         delete iInternal->iCurrentNVGIcon;
       
   230         }
       
   231 #endif
       
   232     
       
   233     delete iInternal;
       
   234     }
       
   235 
       
   236 /**
       
   237  * @brief  Set the angle for rotation of the NVG graphic
       
   238  * @version
       
   239  * @param    aAngle counter-clockwise rotation by a given angle (expressed in degrees)
       
   240  *              aX, aY  point around which the rotation must take place
       
   241  * @return  None
       
   242  */
       
   243 EXPORT_C void CNvgEngine::Rotate(TReal32 aAngle, TReal32 aCentreX, TReal32 aCentreY) __SOFTFP
       
   244     {
       
   245     if(aAngle)
       
   246         {
       
   247         iRotateApplied  = ETrue;
       
   248         iCentreX        = aCentreX;
       
   249         iCentreY        = aCentreY;
       
   250         iRotateAngle    = aAngle;
       
   251         }
       
   252     else
       
   253         {
       
   254         iRotateApplied  = EFalse;
       
   255         iCentreX        = 0;
       
   256         iCentreY        = 0;
       
   257         iRotateAngle    = 0;
       
   258         }
       
   259     }
       
   260 
       
   261 /**
       
   262  * @brief  Gets the viewbox width and height from the NVG bytedata
       
   263  * @version
       
   264  * @param   aBuf NVG byte data of the file
       
   265  * @return  content dimension
       
   266  */
       
   267 EXPORT_C TSize CNvgEngine::ContentDimensions(const TDesC8& aBuf)
       
   268     {
       
   269     if (aBuf.Length() < KNVG_VIEWBOX_HEIGHT_OFS + sizeof (TReal32))
       
   270         {
       
   271         return TSize(0, 0);
       
   272         }
       
   273     
       
   274     const TUint8* lBuf = aBuf.Ptr();
       
   275     TReal32 lViewboxWidth = * (TReal32*)(lBuf + KNVG_VIEWBOX_WIDTH_OFS);
       
   276     TReal32 lViewboxHeight = * (TReal32*)(lBuf + KNVG_VIEWBOX_HEIGHT_OFS);
       
   277     
       
   278     if (lViewboxWidth > 0 && lViewboxHeight > 0)
       
   279         {
       
   280         return TSize(lViewboxWidth, lViewboxHeight);
       
   281         }
       
   282     else
       
   283         {
       
   284         return TSize(0, 0);
       
   285         }
       
   286     }
       
   287 
       
   288 TInt CNvgEngine::InitializeGC()
       
   289     {
       
   290     if (iPaintFill == VG_INVALID_HANDLE)
       
   291         {
       
   292         iPaintFill = vgCreatePaint();
       
   293         if (iPaintFill == VG_INVALID_HANDLE)
       
   294             {
       
   295             return OpenVGErrorToSymbianError(vgGetError());
       
   296             }
       
   297         }
       
   298     
       
   299     vgSetPaint(iPaintFill, VG_FILL_PATH);
       
   300     if (iPaintStroke == VG_INVALID_HANDLE)
       
   301         {
       
   302         iPaintStroke = vgCreatePaint();
       
   303         if (iPaintStroke == VG_INVALID_HANDLE)
       
   304             {
       
   305             return OpenVGErrorToSymbianError(vgGetError());
       
   306             }
       
   307         }
       
   308     
       
   309     vgSetPaint( iPaintStroke, VG_STROKE_PATH);
       
   310     
       
   311     return KErrNone;
       
   312     }
       
   313 
       
   314 EXPORT_C void CNvgEngine::ResetNvgState()
       
   315     {
       
   316     if (iPath != VG_INVALID_HANDLE)
       
   317         {
       
   318         vgDestroyPath(iPath);
       
   319         iPath = VG_INVALID_HANDLE;
       
   320         }
       
   321     
       
   322     if (iPaintFill != VG_INVALID_HANDLE)
       
   323         {
       
   324         vgSetPaint(VG_INVALID_HANDLE, VG_FILL_PATH);
       
   325         vgDestroyPaint(iPaintFill);
       
   326         iPaintFill = VG_INVALID_HANDLE;
       
   327         }
       
   328 		
       
   329     if (iPaintStroke != VG_INVALID_HANDLE)
       
   330         {
       
   331         vgSetPaint(VG_INVALID_HANDLE, VG_STROKE_PATH);
       
   332         vgDestroyPaint(iPaintStroke);
       
   333         iPaintStroke = VG_INVALID_HANDLE;
       
   334         }
       
   335     }
       
   336 
       
   337 EXPORT_C TInt CNvgEngine::DrawNvg(const TDesC8& aBuf, const TSize& aSize, CFbsBitmap* aDstBitmap, CFbsBitmap* aMask)
       
   338     {
       
   339     TInt error = KErrNone;
       
   340     
       
   341     /*
       
   342      * Get Matrix modes and all caller matrices (must be restored afterwards)
       
   343      */ 
       
   344     UpdateClientMatrices();
       
   345     
       
   346     TRAP(error, DoDrawNVGL(aBuf, aSize, aDstBitmap, aMask));
       
   347     
       
   348     /*
       
   349      * restore everything as we may have changed matrix mode
       
   350      */             
       
   351     RestoreClientMatrices();
       
   352 	vgSeti(VG_SCISSORING, VG_FALSE);
       
   353 
       
   354 	if (error)
       
   355 	    {
       
   356 	    NVG_DEBUGP2("Error in NVG rendering %d", error);
       
   357 	    }
       
   358     return error;
       
   359     }
       
   360 
       
   361 EXPORT_C MNVGIcon * CNvgEngine::CreateNVGIcon(const TDesC8& aBuf, const TSize& aSize)
       
   362     {    
       
   363     NVG_DEBUGP1("Creating NVGCSIcon");
       
   364     
       
   365     MNVGIcon * nvgIcon = 0;
       
   366 
       
   367     /*
       
   368      * this is bit unreadable,
       
   369      * need to find a better design to separate the object caching solution from normal rendering,
       
   370      * but anyway I guess its better than those ifdef's, in that code scanner won't give any warnings
       
   371      */
       
   372     COND_COM_OC_NOC(
       
   373     {
       
   374     if (iInternal->iCurrentNVGIcon)
       
   375         {
       
   376         delete iInternal->iCurrentNVGIcon;
       
   377         }
       
   378     
       
   379     iInternal->iCurrentNVGIcon     = 0;
       
   380     iInternal->iCreatingNVGIcon    = 1;
       
   381     
       
   382     if (DrawNvg(aBuf, aSize, 0, 0) != KErrNone)
       
   383         {
       
   384         delete iInternal->iCurrentNVGIcon;
       
   385         iInternal->iCurrentNVGIcon = 0;
       
   386         }
       
   387     
       
   388     iInternal->iCreatingNVGIcon    = 0;
       
   389     nvgIcon = iInternal->iCurrentNVGIcon;
       
   390     iInternal->iCurrentNVGIcon = 0;
       
   391     },
       
   392     {
       
   393     (void)aBuf;
       
   394     (void)aSize;
       
   395     });
       
   396 
       
   397     return nvgIcon;
       
   398     }
       
   399 
       
   400 void CNvgEngine::DoDrawNVGL(const TDesC8& aBuffer, const TSize& aSize, CFbsBitmap* aDstBitmap, CFbsBitmap* aMask)
       
   401     {
       
   402     TInt drawStatus = KErrNone;
       
   403 
       
   404     if (iCurrentBufferSize != aSize)
       
   405         { 
       
   406         iCurrentBufferSize = aSize;
       
   407         }
       
   408     
       
   409     iDstBimtap = aDstBitmap;
       
   410     
       
   411     TDereferencer nvgIconData(aBuffer);
       
   412 
       
   413     TUint8 * signature = nvgIconData.DerefInt8ArrayL(KNVG_SIGNATURE_LENGTH);
       
   414 
       
   415     // checking the 'nvg' signature
       
   416     if (Mem::Compare(signature, KNVG_SIGNATURE_LENGTH, KNVG_SIGNATURE, KNVG_SIGNATURE_LENGTH) != 0)
       
   417         {
       
   418         NVG_DEBUGP1("Not an NVG icon");
       
   419         User::Leave(KErrNotSupported);
       
   420         }
       
   421 
       
   422     // last two bits are for identifying the nvg type. currently nvg-cs or nvg-tlv
       
   423     TUint16   nvgType = nvgIconData.DerefInt16L(KOffsetReserved1) & 0x03;
       
   424     
       
   425     switch (nvgType)
       
   426         {
       
   427         case ENVGCS:
       
   428             {
       
   429             drawStatus = DrawCommandSectionL(&nvgIconData, aSize, aDstBitmap, aMask);
       
   430             break;
       
   431             }
       
   432         case ENVGTLV:
       
   433             {
       
   434             drawStatus = DrawTLVL(aBuffer, aSize, aDstBitmap, aMask);
       
   435             break;
       
   436             }
       
   437         default:
       
   438             drawStatus = KErrNotSupported;
       
   439             break;
       
   440         }
       
   441     
       
   442     User::LeaveIfError(drawStatus);
       
   443     }
       
   444 
       
   445 TInt CNvgEngine::DrawTLVL(const TDesC8& aBuf, const TSize& aTargetSize, CFbsBitmap* /*aDstBitmap*/, CFbsBitmap * /*aMask*/)
       
   446     {
       
   447     TInt ret = KErrNone;
       
   448     
       
   449     // Try to set user's matrix to path matrix
       
   450     VGfloat origMatrix[9];
       
   451     vgGetMatrix(origMatrix);
       
   452     
       
   453     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); 
       
   454     vgLoadMatrix(origMatrix);
       
   455     
       
   456 #ifndef __MIRROR_
       
   457     vgScale(1.0f, -1.0f);
       
   458     vgTranslate(0, (VGfloat)(-iCurrentBufferSize.iHeight));
       
   459 #endif
       
   460 
       
   461     /*
       
   462      * this is bit unreadable,
       
   463      * need to find a better design to separate the object caching solution from normal rendering,
       
   464      * but anyway I guess its better than those ifdef's, in that code scanner won't give any warnings
       
   465      */
       
   466     COND_COM_OC_NOC(
       
   467     {
       
   468     if (iInternal->iCreatingNVGIcon)
       
   469         {
       
   470         iInternal->iCurrentNVGIcon = CNVGTLVIcon::NewL();
       
   471         TLVICON(iInternal->iCurrentNVGIcon)->SetVGImageBinder(iVGImageBinder);
       
   472         TLVICON(iInternal->iCurrentNVGIcon)->CreateL(aBuf, aTargetSize);
       
   473         }
       
   474     else
       
   475         {
       
   476         CNVGTLVIcon * tlvIcon = CNVGTLVIcon::NewL();
       
   477         CleanupStack::PushL(tlvIcon);
       
   478         tlvIcon->SetVGImageBinder(iVGImageBinder);
       
   479         tlvIcon->DirectDrawL(aBuf, aTargetSize);
       
   480         CleanupStack::PopAndDestroy(tlvIcon);        
       
   481         }
       
   482 
       
   483     },
       
   484     {
       
   485     CNVGTLVIcon * tlvIcon = CNVGTLVIcon::NewL();
       
   486     CleanupStack::PushL(tlvIcon);
       
   487     TLVICON(tlvIcon)->SetVGImageBinder(iVGImageBinder);
       
   488     TLVICON(tlvIcon)->DirectDrawL(aBuf, aTargetSize);
       
   489     CleanupStack::PopAndDestroy(tlvIcon);                    
       
   490     });
       
   491     
       
   492     vgSeti(VG_SCISSORING, VG_FALSE);
       
   493     
       
   494     return ret;
       
   495     }
       
   496 
       
   497 TInt CNvgEngine::CreatePathHandle(TInt16 aPathDataType, TReal32 aScale, TReal32 aBias)
       
   498     {
       
   499     (void) aScale;
       
   500     (void) aBias;
       
   501     
       
   502     TInt error = KErrNone;
       
   503     
       
   504     if (iLastPathDataType != aPathDataType)
       
   505         {
       
   506         if (iPath != VG_INVALID_HANDLE)
       
   507             {
       
   508             vgDestroyPath(iPath);
       
   509             iPath = VG_INVALID_HANDLE;
       
   510             }
       
   511         }
       
   512     
       
   513     if (iPath == VG_INVALID_HANDLE)
       
   514         {
       
   515         switch (aPathDataType)
       
   516             {
       
   517             case EEightBitEncoding:
       
   518                 {
       
   519                 iPath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
       
   520                 VG_PATH_DATATYPE_S_16, 1.0f/2.0f, 0.0f, 0, 0,
       
   521                 VG_PATH_CAPABILITY_APPEND_TO);            
       
   522                 }
       
   523                 break;
       
   524                        
       
   525             case ESixteenBitEncoding:
       
   526                 {
       
   527                 iPath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
       
   528                 VG_PATH_DATATYPE_S_16, 1.0f/16.0f, 0.0f, 0, 0,
       
   529                 VG_PATH_CAPABILITY_APPEND_TO);            
       
   530                 }
       
   531                 break;
       
   532                        
       
   533             case EThirtyTwoBitEncoding:
       
   534                 {
       
   535                 iPath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
       
   536                 VG_PATH_DATATYPE_S_32, 1.0f/65536.0f, 0.0f, 0, 0,
       
   537                 VG_PATH_CAPABILITY_APPEND_TO);            
       
   538                 }
       
   539                 break;
       
   540                        
       
   541             default:
       
   542                 {   
       
   543                 return KErrCorrupt;
       
   544                 }
       
   545             }
       
   546         }
       
   547     
       
   548     if( iPath == VG_INVALID_HANDLE )
       
   549         {
       
   550         // get the symbian error code
       
   551         error = OpenVGErrorToSymbianError(vgGetError());
       
   552         
       
   553         if (error == KErrNoMemory)
       
   554             {
       
   555             NVG_DEBUGP1("NVG Error OOM");
       
   556             ResetNvgState();
       
   557             }
       
   558         return error;
       
   559         }
       
   560     
       
   561     iLastPathDataType   = aPathDataType;
       
   562 
       
   563     return error;
       
   564     }
       
   565 
       
   566 TInt CNvgEngine::DrawCommandSectionL(TDereferencer * aIconData, const TSize& aTargetSize, CFbsBitmap * /*aDstBitmap*/, CFbsBitmap * /*aMask*/)
       
   567     {
       
   568     TInt16 lHeaderSize  = aIconData->DerefInt16L(KNVG_HEADERSIZE_OFS);
       
   569     TInt8 NVGVersion    = aIconData->DerefInt8L(KNVG_VERSION_OFS);
       
   570     
       
   571     User::LeaveIfError(InitializeGC());
       
   572 
       
   573     TInt16 lPathDataType = aIconData->DerefInt16L(KNVG_PATHDATATYPE_OFS);
       
   574     TReal32 lScale       = aIconData->DerefReal32L(KNVG_SCALE_OFS);
       
   575     TReal32 lBias        = aIconData->DerefReal32L(KNVG_BIAS_OFS);
       
   576 
       
   577     User::LeaveIfError(CreatePathHandle(lPathDataType, lScale, lBias));
       
   578     
       
   579     vgSetPaint(iPaintFill, VG_FILL_PATH);
       
   580     
       
   581     COND_COM_OC_OOC(
       
   582     if (iInternal->iCreatingNVGIcon)
       
   583         {
       
   584         iInternal->iCurrentNVGIcon = CNVGCSIcon::NewL(aIconData->GetPtr());
       
   585         });
       
   586     
       
   587     VGfloat lCurrentPathMatrix[9];
       
   588     vgGetMatrix(lCurrentPathMatrix);
       
   589     
       
   590     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);  
       
   591     
       
   592     /*
       
   593      * We use the caller's base batrix regardless of which mode the caller was.
       
   594      * The caller may have set the matrix in VG_MATRIX_IMAGE_USER_TO_SURFACE mode
       
   595      * as it thinks it is drawing images (textures).
       
   596      * But even though the texture gets stroked instead, we must use the caller's
       
   597      * transformation matrix.
       
   598      * Everything gets restored to the original values before we return.
       
   599      */
       
   600     vgLoadMatrix(lCurrentPathMatrix);
       
   601     
       
   602     ApplyScissoring(lCurrentPathMatrix, aTargetSize);
       
   603 
       
   604     /*
       
   605      * set the rotation angle if available
       
   606      */
       
   607     if (iRotateApplied)
       
   608         {           
       
   609         ApplyRotation();
       
   610         }
       
   611     
       
   612 #ifdef __MIRROR_    
       
   613     vgScale(1.0f, -1.0f);
       
   614     vgTranslate(0, (VGfloat)(-iCurrentBufferSize.iHeight) );
       
   615 #endif
       
   616         
       
   617     TReal32 lViewboxX   = aIconData->DerefReal32L(KNVG_VIEWBOX_X_OFS);
       
   618     TReal32 lViewboxY   = aIconData->DerefReal32L(KNVG_VIEWBOX_Y_OFS);
       
   619     TReal32 lViewboxW   = aIconData->DerefReal32L(KNVG_VIEWBOX_WIDTH_OFS);
       
   620     TReal32 lViewboxH   = aIconData->DerefReal32L(KNVG_VIEWBOX_HEIGHT_OFS);
       
   621      
       
   622     ApplyViewboxToViewPortTransformationL(aTargetSize, lViewboxX, lViewboxY, lViewboxW, lViewboxH);
       
   623     
       
   624     TPtr8 ptr = aIconData->GetPtr();
       
   625     
       
   626     TInt offsetSectionLength = aIconData->GetLength() - lHeaderSize;
       
   627     TUint8 * offsetPtr = aIconData->DerefInt8ArrayL(offsetSectionLength, lHeaderSize);
       
   628     
       
   629     TDereferencer offsetSection(offsetPtr, offsetSectionLength);
       
   630 
       
   631     TUint16 lOffsetVectorCount  = offsetSection.DerefInt16L();
       
   632 
       
   633     offsetPtr = aIconData->DerefInt8ArrayL(offsetSectionLength - sizeof(TUint16), lHeaderSize + sizeof(TUint16));
       
   634     TDereferencer offsetVector(offsetPtr, offsetSectionLength - sizeof(TUint16));
       
   635 
       
   636     idoFill     = VG_FALSE;
       
   637     idoStroke   = VG_FALSE;
       
   638     
       
   639     TPtr8 offsetTPtr = offsetVector.GetPtr();
       
   640     
       
   641     TInt commandSectionOffset = lOffsetVectorCount * sizeof(TUint16);
       
   642     TDereferencer commandSection((unsigned char*)(offsetTPtr.Ptr() + commandSectionOffset), 
       
   643             aIconData->GetLength() - commandSectionOffset - lHeaderSize - sizeof(TUint16));
       
   644 
       
   645     // from version 2 onwards command section will start on word boundary
       
   646     if (NVGVersion >= KVersion2 && ((lOffsetVectorCount  & 0x01) == 0))
       
   647         {
       
   648         commandSection.SkipL(2);
       
   649         }
       
   650     
       
   651     TUint16 lCmdCount = commandSection.DerefInt16L();
       
   652     
       
   653     commandSection.SkipL(KNVG_COMMANDSECTION_OFS);
       
   654 
       
   655     /*
       
   656      * from version 2 onwards there will be a padding added
       
   657      * after the command count to make it word aligned
       
   658      */
       
   659     if (NVGVersion >= KVersion2)
       
   660         {
       
   661         commandSection.SkipL(2);
       
   662         }
       
   663 
       
   664     ExecuteNVGCSCommandLoopL(lCmdCount, aIconData, &offsetVector, &commandSection, NVGVersion);
       
   665     
       
   666     return KErrNone;
       
   667     }
       
   668 
       
   669 void CNvgEngine::ApplyRotation()
       
   670     {
       
   671     vgTranslate(iCentreX, iCentreY);  
       
   672     vgRotate(iRotateAngle);
       
   673     vgTranslate(-iCentreX, -iCentreY);
       
   674     }
       
   675 
       
   676 void CNvgEngine::ApplyScissoring(VGfloat aMatrix[], const TSize& aTargetSize)
       
   677     {
       
   678     /*
       
   679      * calculate the rectangle with respect to the transformation applied
       
   680      * and set the scissoring rect
       
   681      */ 
       
   682     TPoint leftBottom  = GetTranslatedPoint(aMatrix, TPoint(0, 0));
       
   683     TPoint leftTop     = GetTranslatedPoint(aMatrix, TPoint(0, aTargetSize.iHeight));
       
   684     TPoint rightBottom = GetTranslatedPoint(aMatrix, TPoint(aTargetSize.iWidth, 0));
       
   685     TPoint rightTop    = GetTranslatedPoint(aMatrix, TPoint(aTargetSize.iWidth,aTargetSize.iHeight));
       
   686 
       
   687     VGfloat minX = leftBottom.iX;
       
   688     VGfloat minY = leftBottom.iY;
       
   689     VGfloat maxX = leftBottom.iX;
       
   690     VGfloat maxY = leftBottom.iY;
       
   691 
       
   692     minX = MinVal4(leftBottom.iX, leftTop.iX, rightBottom.iX, rightTop.iX);
       
   693     minY = MinVal4(leftBottom.iY, leftTop.iY, rightBottom.iY, rightTop.iY);
       
   694 
       
   695     maxX = MaxVal4(leftBottom.iX, leftTop.iX, rightBottom.iX, rightTop.iX);
       
   696     maxY = MaxVal4(leftBottom.iY, leftTop.iY, rightBottom.iY, rightTop.iY);
       
   697 
       
   698     VGfloat newW = maxX - minX;
       
   699     VGfloat newH = maxY - minY;
       
   700 
       
   701     VGint clipRect[] = {minX, minY, newW, newH};
       
   702 
       
   703     vgSeti(VG_SCISSORING, VG_TRUE);
       
   704     vgSetiv(VG_SCISSOR_RECTS, 4,(const TInt32*) clipRect);
       
   705     }
       
   706 
       
   707 void CNvgEngine::ApplyViewboxToViewPortTransformationL(const TSize& aTargetSize, TReal32 aViewboxX, TReal32 aViewboxY, TReal32 aViewboxW, TReal32 aViewboxH)
       
   708     {
       
   709     CNvgFitToViewBoxImpl * viewboxTrnsfr =  CNvgFitToViewBoxImpl::NewL();
       
   710     CleanupStack::PushL(viewboxTrnsfr);
       
   711     /*
       
   712      * this is bit unreadable,
       
   713      * need to find a better design to separate the object caching solution from normal rendering,
       
   714      * but anyway I guess its better than those ifdef's, in that code scanner won't give any warnings
       
   715      */
       
   716     COND_COM_OC_NOC(
       
   717     {
       
   718     if (iInternal->iCreatingNVGIcon)
       
   719         {
       
   720         CSICON(iInternal->iCurrentNVGIcon)->SetViewBox(aViewboxX, aViewboxY, aViewboxW, aViewboxH);
       
   721         CSICON(iInternal->iCurrentNVGIcon)->SetPreserveAspectRatio(iPreserveAspectSetting, iSmilFitSetting);
       
   722         CSICON(iInternal->iCurrentNVGIcon)->Rotate(iRotateAngle, iCentreX, iCentreY);
       
   723         }
       
   724     else
       
   725         {
       
   726         viewboxTrnsfr->SetAlign(iPreserveAspectSetting);
       
   727         viewboxTrnsfr->SetScaling(iSmilFitSetting);
       
   728         
       
   729         if (aViewboxW > 0 && aViewboxH > 0)
       
   730             {
       
   731             viewboxTrnsfr->SetViewBox(aViewboxX, aViewboxY, aViewboxW, aViewboxH);
       
   732             }
       
   733         
       
   734         TInt lWidth = aTargetSize.iWidth;
       
   735         TInt lHeight = aTargetSize.iHeight;
       
   736         
       
   737         viewboxTrnsfr->SetWindowViewportTrans(TRect(0, 0, lWidth, lHeight), TSize(0, 0));
       
   738         
       
   739         }
       
   740     },
       
   741     {
       
   742     viewboxTrnsfr->SetAlign(iPreserveAspectSetting);
       
   743     viewboxTrnsfr->SetScaling(iSmilFitSetting);
       
   744     
       
   745     if (aViewboxW > 0 && aViewboxH > 0)
       
   746         {
       
   747         viewboxTrnsfr->SetViewBox(aViewboxX, aViewboxY, aViewboxW, aViewboxH);
       
   748         }
       
   749     
       
   750     TInt lWidth = aTargetSize.iWidth;
       
   751     TInt lHeight = aTargetSize.iHeight;
       
   752     
       
   753     viewboxTrnsfr->SetWindowViewportTrans(TRect(0, 0, lWidth, lHeight), TSize(0, 0));
       
   754     });
       
   755     
       
   756     CleanupStack::PopAndDestroy(viewboxTrnsfr);
       
   757     }
       
   758 
       
   759 TDereferencer GetCommandSectionL(TUint16 aOffset, TDereferencer * aIconData, TInt aNVGVersion)
       
   760     {
       
   761     // the max length that the command section can have
       
   762     TInt commandSectionLength = aIconData->GetLength() - aOffset;
       
   763 
       
   764     if (commandSectionLength <= 0)
       
   765         {
       
   766         User::Leave(KErrCorrupt);
       
   767         }
       
   768 
       
   769     TDereferencer section(aIconData->DerefInt8ArrayL(commandSectionLength, aOffset), commandSectionLength);
       
   770 
       
   771     /*
       
   772      * all the section are expected to be word aligned
       
   773      * all of the nvg-cs icon will be version 2 or above
       
   774      * the else won't be there as nvg version will always be greater than 2
       
   775      */
       
   776     if (aNVGVersion >= KVersion2)
       
   777         {
       
   778         if (!IsAligned4(aOffset))
       
   779             {
       
   780             User::Leave(KErrCorrupt);
       
   781             }
       
   782         }
       
   783     else
       
   784         {
       
   785         /*
       
   786          * no need to do anything here as once the nvgdecoder release
       
   787          * its version will be always greater than 2
       
   788          * infact the check for version will be removed
       
   789          */ 
       
   790         }
       
   791     
       
   792     return section;
       
   793     }
       
   794 
       
   795 void CNvgEngine::ExecuteNVGCSCommandLoopL(TUint16 aCommandCount, TDereferencer * aIconData, TDereferencer * aOffsetVector,
       
   796                                           TDereferencer * aCommandSection, TInt aNVGVersion)
       
   797     {
       
   798     TUint32 transVal;
       
   799 
       
   800     VGfloat lCurrentPathMatrix[9];
       
   801     
       
   802     vgGetMatrix(lCurrentPathMatrix);
       
   803     
       
   804     TInt32 lOffsetIx = 0;
       
   805     for (TInt i=0; i < aCommandCount; i++)
       
   806         {
       
   807         TUint32 currentCommand = aCommandSection->DerefInt32L();
       
   808         lOffsetIx = currentCommand & 0x0000ffff;
       
   809                 
       
   810         switch (currentCommand & 0xff000000)
       
   811             {
       
   812             case KCMD_SET_FILL_PAINT:
       
   813                 {
       
   814                 iFillAlpha        = (currentCommand & 0x00ff0000) >> 16;
       
   815                 TUint16 offset    = aOffsetVector->DerefInt16L(lOffsetIx * sizeof(TUint16));
       
   816                 
       
   817                 TDereferencer section = GetCommandSectionL(offset, aIconData, aNVGVersion);
       
   818                                 
       
   819                 SetFillPaintL(&section);
       
   820                 
       
   821                 break;
       
   822                 }
       
   823                 
       
   824             case KCMD_SET_COLOR_RAMP:
       
   825                 {
       
   826                 TUint16 offset = aOffsetVector->DerefInt16L(lOffsetIx * sizeof(TUint16));
       
   827 
       
   828                 TDereferencer section = GetCommandSectionL(offset, aIconData, aNVGVersion);
       
   829 
       
   830                 SetColorRampL(&section);
       
   831                 
       
   832                 break;
       
   833                 }
       
   834                 
       
   835             case KCMD_DRAW_PATH:
       
   836                 {
       
   837                 if ((currentCommand & 0x00010000)) 
       
   838                     {
       
   839                     idoStroke = VG_TRUE;
       
   840                     }
       
   841                 
       
   842                 if ((currentCommand & 0x00020000))
       
   843                     {
       
   844                     idoFill = VG_TRUE;
       
   845                     }
       
   846                 
       
   847                 if (idoStroke != VG_FALSE || idoFill != VG_FALSE)
       
   848                     {
       
   849                     TUint16 offset        = aOffsetVector->DerefInt16L(lOffsetIx * sizeof(TUint16));    
       
   850                     TDereferencer section = GetCommandSectionL(offset, aIconData, aNVGVersion);
       
   851     
       
   852                     DrawPathL(&section);
       
   853                     }
       
   854                 
       
   855                 break;
       
   856                 }
       
   857                 
       
   858             case KCMD_SET_TRANSFORMATION:
       
   859                 {
       
   860                 SetTransformL(aCommandSection, transVal, lCurrentPathMatrix);
       
   861                 aCommandSection->SkipL(transVal * sizeof(TUint32));
       
   862                 break;
       
   863                 }
       
   864                 
       
   865             case KCMD_SET_STROKE_PAINT:
       
   866                 {
       
   867                 iStrokeAlpha = (currentCommand & 0x00ff0000) >> 16;
       
   868                 TUint16 offset = aOffsetVector->DerefInt16L(lOffsetIx * sizeof(TUint16));
       
   869 
       
   870                 TDereferencer section = GetCommandSectionL(offset, aIconData, aNVGVersion);
       
   871 
       
   872                 SetStrokePaintL(&section);
       
   873                 
       
   874                 break;
       
   875                 }
       
   876 
       
   877             case KCMD_SET_STROKE_WIDTH:
       
   878                 {
       
   879                 TReal32 lStrokeWidth;
       
   880                 aCommandSection->SkipL(sizeof(TUint32));
       
   881                 
       
   882                 /*
       
   883                  * check for alignment and copy data if not aligned, else directly convert
       
   884                  * version 2 or above guarantees that is always word aligned
       
   885                  */
       
   886                 TUint8 * cptr = aCommandSection->DerefInt8ArrayL(sizeof(TReal32), 0); 
       
   887                 if (aNVGVersion < KVersion2 && !IsAligned4(cptr))
       
   888                     {
       
   889                     
       
   890                     Mem::Copy(reinterpret_cast<void *>(&lStrokeWidth),
       
   891                               reinterpret_cast<void *>(cptr), sizeof(lStrokeWidth));
       
   892                     }
       
   893                 else
       
   894                     {
       
   895                     lStrokeWidth = aCommandSection->DerefReal32L();
       
   896                     }
       
   897                 
       
   898                 COND_COM_OC(iInternal->iCreatingNVGIcon,
       
   899                         CSICON(iInternal->iCurrentNVGIcon)->AddSetStrokeWidthCommandL(lStrokeWidth),
       
   900                         vgSetf(VG_STROKE_LINE_WIDTH, lStrokeWidth));
       
   901                 break;
       
   902                 }
       
   903                 
       
   904             case KCMD_SET_STROKE_MITER_LIMIT:
       
   905                 {
       
   906                 TReal32 lMiterLimit;
       
   907                 aCommandSection->SkipL(sizeof(TUint32));
       
   908 
       
   909                 /*
       
   910                  * check for alignment and copy data if not aligned, else directly convert
       
   911                  * version 2 or above guarantees that is always word aligned
       
   912                  */
       
   913                 TUint8 * cptr = aCommandSection->DerefInt8ArrayL(sizeof(TReal32), 0); 
       
   914 
       
   915                 if (aNVGVersion < KVersion2 && !IsAligned4(cptr))
       
   916                     {
       
   917                     Mem::Copy(reinterpret_cast<void *>(&lMiterLimit),
       
   918                               reinterpret_cast<void *>(cptr), sizeof(lMiterLimit));
       
   919                     }
       
   920                 else
       
   921                     {
       
   922                     lMiterLimit = aCommandSection->DerefReal32L();
       
   923                     }
       
   924                 
       
   925                 COND_COM_OC(iInternal->iCreatingNVGIcon,
       
   926                         CSICON(iInternal->iCurrentNVGIcon)->AddSetStrokeMiterLimitCommandL(lMiterLimit),
       
   927                         vgSetf(VG_STROKE_MITER_LIMIT, lMiterLimit));
       
   928                 
       
   929                 break;
       
   930                 }
       
   931                 
       
   932             case KCMD_SET_STROKE_LINE_JOIN_CAP:
       
   933                 {
       
   934                 TUint8 lJoinType =(currentCommand & 0x0000ff00)>>8;
       
   935                 TUint8 lCapType = (currentCommand & 0x000000ff);
       
   936                 
       
   937                 VGCapStyle capStyle;
       
   938                 switch(lCapType)
       
   939                     {
       
   940                     case KCAP_SQUARE:
       
   941                         capStyle = VG_CAP_SQUARE;
       
   942                         break;
       
   943                     case KCAP_ROUND:
       
   944                         capStyle = VG_CAP_ROUND;
       
   945                         break;
       
   946                     case KCAP_BUTT:
       
   947                     default:
       
   948                         capStyle = VG_CAP_BUTT;
       
   949                         break;
       
   950                     }
       
   951    
       
   952                 VGJoinStyle lineJoinStyle;
       
   953                 switch(lJoinType)
       
   954                     {
       
   955                     case KLINE_JOIN_BEVEL:
       
   956                         lineJoinStyle = VG_JOIN_BEVEL;
       
   957                         break;
       
   958                     case KLINE_JOIN_ROUND:
       
   959                         lineJoinStyle = VG_JOIN_ROUND;
       
   960                         break;
       
   961                     case KLINE_JOIN_MITER:
       
   962                     default:
       
   963                         lineJoinStyle = VG_JOIN_MITER;
       
   964                         break;
       
   965                     }
       
   966                 
       
   967                 COND_COM_OC(iInternal->iCreatingNVGIcon,
       
   968                         CSICON(iInternal->iCurrentNVGIcon)->AddStrokeLineJoinCapCommandL(capStyle, lineJoinStyle),
       
   969                         vgSeti(VG_STROKE_CAP_STYLE, capStyle);
       
   970                         vgSeti(VG_STROKE_JOIN_STYLE, lineJoinStyle););
       
   971                 break;
       
   972                 }
       
   973                 
       
   974             default:
       
   975                 {
       
   976                 User::Leave(KErrCorrupt);
       
   977                 break;
       
   978                 }
       
   979             }
       
   980         
       
   981         // go to the next command
       
   982         aCommandSection->SkipL(sizeof(TUint32));
       
   983         }
       
   984     }
       
   985 
       
   986 EXPORT_C void CNvgEngine::SetPreserveAspectRatio(
       
   987         TNvgAlignStatusType aPreserveAspectSetting, 
       
   988         TNvgMeetOrSliceType aSmilFitSetting)
       
   989     {
       
   990     iPreserveAspectSetting = aPreserveAspectSetting;
       
   991     iSmilFitSetting = aSmilFitSetting;
       
   992     }
       
   993 
       
   994 EXPORT_C void CNvgEngine::SetBackgroundColor(TUint32 aRGBA8888Color)
       
   995     {
       
   996     iBackgroundColor = aRGBA8888Color;
       
   997     }
       
   998 
       
   999 TInt CNvgEngine::SetFillPaintL(TDereferencer * aIconData)
       
  1000     {
       
  1001     COND_COM_OC_OOC(register int drawingMode = iInternal->iCreatingNVGIcon);
       
  1002     
       
  1003     TUint32 lCommonData  = aIconData->DerefInt32L();
       
  1004     TUint lPaintType     = lCommonData & 0x07;
       
  1005     TUint16 lSpecifcData = (lCommonData >> 16) & 0xff;
       
  1006     
       
  1007     switch (lPaintType)
       
  1008         {
       
  1009         case KPAINT_LGRAD:
       
  1010             {
       
  1011             iGradPaintFill = iPaintFill;
       
  1012             
       
  1013             COND_COM_OC_OOC(
       
  1014             if (iInternal->iCreatingNVGIcon)
       
  1015                 {
       
  1016                 // CNVGCSIcon will destroy the paint handle
       
  1017                 iGradPaintFill = vgCreatePaint();
       
  1018                 if (iGradPaintFill == VG_INVALID_HANDLE)
       
  1019                     {
       
  1020                     User::LeaveIfError(CNvgEngine::OpenVGErrorToSymbianError(vgGetError()));
       
  1021                     }
       
  1022                 });
       
  1023 
       
  1024             // gradient data, the data will be word aligned
       
  1025             TReal32* lGradData = (TReal32*)aIconData->DerefInt8ArrayL(4 * sizeof(VGfloat), sizeof(TUint32));
       
  1026             
       
  1027             vgSetParameteri(iGradPaintFill, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
       
  1028             vgSetParameterfv(iGradPaintFill, VG_PAINT_LINEAR_GRADIENT, 4, lGradData);
       
  1029             vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
  1030             
       
  1031             if (lSpecifcData & 0x1)
       
  1032                 {
       
  1033                 TReal32* lGradMatrix1 = (TReal32*) aIconData->DerefInt8ArrayL(6 * sizeof (VGfloat),
       
  1034                                                     KNVG_PAINTSECTION_LINEARGRAD_TRANSFORM_OFFSET);
       
  1035                 
       
  1036                 TReal32 lGradMatrix[9] = {lGradMatrix1[0], lGradMatrix1[3], 0.0f,  
       
  1037                         lGradMatrix1[1], lGradMatrix1[4], 0.0f,
       
  1038                         lGradMatrix1[2], lGradMatrix1[5], 1.0f};
       
  1039                 
       
  1040                 COND_COM_OC(drawingMode,
       
  1041                         CSICON(iInternal->iCurrentNVGIcon)->AddLinearGradientCommandL(4, lGradData, lGradMatrix, iGradPaintFill),
       
  1042                         vgLoadMatrix(lGradMatrix););
       
  1043                 }
       
  1044             else
       
  1045                 {
       
  1046                 COND_COM_OC(drawingMode,
       
  1047                         CSICON(iInternal->iCurrentNVGIcon)->AddLinearGradientCommandL(4, lGradData, (VGfloat*)KIdentityMatrix, iGradPaintFill),
       
  1048                         vgLoadIdentity());
       
  1049                 }
       
  1050             
       
  1051             COND_COM_OC(drawingMode, ;,
       
  1052                      vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE));
       
  1053             
       
  1054             break;
       
  1055             }
       
  1056             
       
  1057         case KPAINT_RGRAD:
       
  1058             {
       
  1059             // gradient data, the data will be word aligned
       
  1060             TReal32* lGradData = (TReal32*)aIconData->DerefInt8ArrayL(5 * sizeof(VGfloat), sizeof(TUint32));
       
  1061             iGradPaintFill = iPaintFill;
       
  1062             
       
  1063             COND_COM_OC_OOC(
       
  1064             if (iInternal->iCreatingNVGIcon)
       
  1065                 {
       
  1066                 iGradPaintFill = vgCreatePaint();
       
  1067                 if (iGradPaintFill == VG_INVALID_HANDLE)
       
  1068                     {
       
  1069                     User::LeaveIfError(CNvgEngine::OpenVGErrorToSymbianError(vgGetError()));
       
  1070                     }                
       
  1071                 });
       
  1072 
       
  1073             vgSetParameteri(iGradPaintFill, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT);
       
  1074             vgSetParameterfv(iGradPaintFill, VG_PAINT_RADIAL_GRADIENT, 5, lGradData);
       
  1075             vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
  1076 
       
  1077 
       
  1078             if (lSpecifcData & 0x1)
       
  1079                 {
       
  1080                 TReal32* lGradMatrix1 = (TReal32*)aIconData->DerefInt8ArrayL(6 * sizeof (VGfloat),
       
  1081                                                    KNVG_PAINTSECTION_RADIALGRAD_TRANSFORM_OFFSET);
       
  1082                 
       
  1083                 TReal32 lGradMatrix[9] = {lGradMatrix1[0], lGradMatrix1[3], 0.0f,  
       
  1084                         lGradMatrix1[1], lGradMatrix1[4], 0.0f,
       
  1085                         lGradMatrix1[2], lGradMatrix1[5], 1.0f};
       
  1086                 
       
  1087                 COND_COM_OC(drawingMode,
       
  1088                         CSICON(iInternal->iCurrentNVGIcon)->AddRadialGradientCommandL(5, lGradData, lGradMatrix, iGradPaintFill),
       
  1089                         vgLoadMatrix(lGradMatrix));
       
  1090                 }
       
  1091             else
       
  1092                 {
       
  1093                 COND_COM_OC(drawingMode,
       
  1094                         CSICON(iInternal->iCurrentNVGIcon)->AddRadialGradientCommandL(5, lGradData, (VGfloat*)KIdentityMatrix, iGradPaintFill),
       
  1095                         vgLoadIdentity());
       
  1096                 }
       
  1097             
       
  1098             COND_COM_OC(drawingMode, ;,
       
  1099                     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE));
       
  1100             break;
       
  1101             }
       
  1102             
       
  1103         case KPAINT_FLAT:
       
  1104             {
       
  1105             TUint32 lRgba = aIconData->DerefInt32L(KNVG_RGBA_OFS);
       
  1106 
       
  1107             lRgba = (lRgba & 0xffffff00) | iFillAlpha;
       
  1108             
       
  1109             COND_COM_OC(drawingMode,
       
  1110                     CSICON(iInternal->iCurrentNVGIcon)->AddSetColorCommandL(lRgba),
       
  1111                     vgSetParameteri(iPaintFill, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
       
  1112                     vgSetColor(iPaintFill, lRgba));            
       
  1113             break;
       
  1114             }
       
  1115             
       
  1116         default:
       
  1117             {
       
  1118             User::Leave(KErrCorrupt);
       
  1119             break;
       
  1120             }
       
  1121         }
       
  1122     return KErrNone;
       
  1123     }
       
  1124 
       
  1125 TInt CNvgEngine::SetColorRampL(TDereferencer * aIconData)
       
  1126     {
       
  1127     TUint32 lCommonData = aIconData->DerefInt32L();
       
  1128     
       
  1129     TInt lStopCount = (lCommonData >> 16) & 0x00ff;
       
  1130     TReal32* lStopData = (TReal32*)aIconData->DerefInt8ArrayL(lStopCount * 5 * sizeof(TReal32), sizeof(TUint32));
       
  1131     
       
  1132     VGfloat * colorRamps = new (ELeave) VGfloat[lStopCount * 5];
       
  1133     CleanupStack::PushL(TCleanupItem(CleanupArray, colorRamps));
       
  1134         
       
  1135     if (iFillAlpha == 0xff)
       
  1136         {
       
  1137         vgSetParameteri(iGradPaintFill, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
       
  1138         vgSetParameterfv(iGradPaintFill, VG_PAINT_COLOR_RAMP_STOPS, lStopCount * 5, lStopData);
       
  1139         }
       
  1140     else
       
  1141         {
       
  1142         // Copy color ramps and modify alpha
       
  1143         memcpy(colorRamps, lStopData, lStopCount * 5 * sizeof(VGfloat));
       
  1144         
       
  1145         VGfloat lAlphaInFloat = iFillAlpha * (1.0f/255.0f);
       
  1146         VGfloat* lAlphaValue  = &colorRamps[4];
       
  1147         
       
  1148         for (int i=0; i<lStopCount; i++)
       
  1149             {
       
  1150             *lAlphaValue *= lAlphaInFloat;
       
  1151             lAlphaValue += 5;
       
  1152             }
       
  1153         
       
  1154         vgSetParameteri(iGradPaintFill, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
       
  1155         vgSetParameterfv(iGradPaintFill, VG_PAINT_COLOR_RAMP_STOPS, lStopCount * 5, colorRamps);       
       
  1156         }
       
  1157     
       
  1158     CleanupStack::PopAndDestroy();
       
  1159     return KErrNone;
       
  1160     }
       
  1161 
       
  1162 void CNvgEngine::SetStrokePaintL(TDereferencer * aIconData)
       
  1163     {
       
  1164     COND_COM_OC_OOC(register int drawingMode = iInternal->iCreatingNVGIcon;);
       
  1165     
       
  1166     TUint32 lCommonData  = aIconData->DerefInt32L();
       
  1167     TUint lStrokeType    = lCommonData & 0x07;
       
  1168     TUint16 lSpecifcData = (lCommonData >> 16) & 0xff;
       
  1169         
       
  1170     switch (lStrokeType)
       
  1171         {
       
  1172         case KSTROKE_LGRAD:
       
  1173             {
       
  1174             iGradPaintStroke = iPaintStroke;
       
  1175             
       
  1176             COND_COM_OC_OOC(
       
  1177             if (iInternal->iCreatingNVGIcon)
       
  1178                 {
       
  1179                 iGradPaintStroke = vgCreatePaint();
       
  1180                 User::LeaveIfNull((TAny *)iGradPaintStroke);
       
  1181                 });
       
  1182 
       
  1183             // gradient data, the data will be word aligned
       
  1184             TReal32* lGradData = (TReal32*)aIconData->DerefInt8ArrayL(4 * sizeof(VGfloat), sizeof(TUint32));
       
  1185             
       
  1186             COND_COM_OC(drawingMode, ;,
       
  1187                     vgSetParameteri( iGradPaintStroke, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT );
       
  1188                     vgSetParameterfv( iGradPaintStroke, VG_PAINT_LINEAR_GRADIENT, 4, lGradData);                
       
  1189                     vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER));
       
  1190                         
       
  1191             if (lSpecifcData & 0x1)
       
  1192                 {
       
  1193                 TReal32* lGradMatrix1 = (TReal32*)aIconData->DerefInt8ArrayL(6 * sizeof(VGfloat),
       
  1194                                                                              4 + 4 * sizeof(VGfloat));
       
  1195                 TReal32 lGradMatrix[9] = {lGradMatrix1[0], lGradMatrix1[3], 0.0f,  
       
  1196                         lGradMatrix1[1], lGradMatrix1[4], 0.0f,
       
  1197                         lGradMatrix1[2], lGradMatrix1[5], 1.0f};
       
  1198                 
       
  1199                 COND_COM_OC(drawingMode,
       
  1200                         CSICON(iInternal->iCurrentNVGIcon)->AddStrokeLinearGradientCommandL(4, lGradData, lGradMatrix, iGradPaintStroke),
       
  1201                         vgLoadMatrix(lGradMatrix));                
       
  1202                 }
       
  1203             else
       
  1204                 {
       
  1205                 COND_COM_OC(drawingMode,
       
  1206                         CSICON(iInternal->iCurrentNVGIcon)->AddStrokeLinearGradientCommandL(4, lGradData, (VGfloat*)KIdentityMatrix, iGradPaintStroke),
       
  1207                         vgLoadIdentity());                
       
  1208                 }
       
  1209             vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1210             break;
       
  1211             }
       
  1212 
       
  1213         case KSTROKE_RGRAD:
       
  1214             {
       
  1215             iGradPaintStroke = iPaintStroke;
       
  1216             
       
  1217             COND_COM_OC_OOC(
       
  1218             if (iInternal->iCreatingNVGIcon)
       
  1219                 {
       
  1220                 iGradPaintStroke = vgCreatePaint();
       
  1221                 User::LeaveIfNull((TAny *)iGradPaintStroke);
       
  1222                 });
       
  1223             
       
  1224             // gradient data, the data will be word aligned
       
  1225             TReal32* lGradData = (TReal32*)aIconData->DerefInt8ArrayL(5 * sizeof(VGfloat), sizeof(TUint32));
       
  1226             
       
  1227             COND_COM_OC(drawingMode, ;,
       
  1228                      vgSetParameteri( iGradPaintStroke, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT );
       
  1229                      vgSetParameterfv( iGradPaintStroke, VG_PAINT_RADIAL_GRADIENT, 5, lGradData);            
       
  1230                      vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER));
       
  1231             
       
  1232             if (lSpecifcData & 0x1)
       
  1233                 {
       
  1234                 TReal32* lGradMatrix1 = (TReal32*)aIconData->DerefInt8ArrayL(6 * sizeof(VGfloat),
       
  1235                                                                              4 + 5 * sizeof(VGfloat));
       
  1236                 TReal32 lGradMatrix[9] = {lGradMatrix1[0], lGradMatrix1[3], 0.0f,  
       
  1237                         lGradMatrix1[1], lGradMatrix1[4], 0.0f,
       
  1238                         lGradMatrix1[2], lGradMatrix1[5], 1.0f};
       
  1239                 
       
  1240                 COND_COM_OC(drawingMode,
       
  1241                         CSICON(iInternal->iCurrentNVGIcon)->AddStrokeRadialGradientCommandL(4, lGradData, lGradMatrix, iGradPaintStroke),
       
  1242                         vgLoadMatrix(lGradMatrix));                
       
  1243                 }
       
  1244             else
       
  1245                 {
       
  1246                 COND_COM_OC(drawingMode,
       
  1247                         CSICON(iInternal->iCurrentNVGIcon)->AddStrokeRadialGradientCommandL(4, lGradData, (VGfloat*)KIdentityMatrix, iGradPaintStroke),
       
  1248                         vgLoadIdentity());
       
  1249                 }
       
  1250             vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1251             break;
       
  1252             }
       
  1253             
       
  1254         case KSTROKE_COLOR_RAMP:
       
  1255             {
       
  1256             TInt lStopCount = lSpecifcData;
       
  1257             TReal32* lStopData = (TReal32*) aIconData->DerefInt8ArrayL(lStopCount * 5 * sizeof(VGfloat), 4);
       
  1258             
       
  1259             if (iStrokeAlpha == 0xff)
       
  1260                 {
       
  1261                  vgSetParameteri(iGradPaintStroke, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
       
  1262                  vgSetParameterfv(iGradPaintStroke, VG_PAINT_COLOR_RAMP_STOPS, lStopCount*5, lStopData);                
       
  1263                 }
       
  1264             else
       
  1265                 {
       
  1266                 VGfloat * colorRamps = new (ELeave) VGfloat[lStopCount * 5];
       
  1267                 CleanupStack::PushL(TCleanupItem(CleanupArray, colorRamps));
       
  1268 
       
  1269                 memcpy(colorRamps, lStopData, lStopCount * 5 * sizeof(VGfloat));
       
  1270                 
       
  1271                 VGfloat lAlphaInFloat = iStrokeAlpha * (1.0f/255.0f);
       
  1272                 VGfloat* lAlphaValue  = &colorRamps[4];
       
  1273                 
       
  1274                 for (int i=0; i<lStopCount; i++)
       
  1275                     {
       
  1276                     *lAlphaValue *= lAlphaInFloat;
       
  1277                     lAlphaValue += 5;
       
  1278                     }
       
  1279                 
       
  1280                 vgSetParameteri(iGradPaintStroke, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
       
  1281                 vgSetParameterfv(iGradPaintStroke, VG_PAINT_COLOR_RAMP_STOPS, lStopCount * 5, colorRamps);
       
  1282                 CleanupStack::PopAndDestroy();
       
  1283                 }
       
  1284             break;
       
  1285             } 
       
  1286             
       
  1287         default:
       
  1288             {
       
  1289             TUint32 lRgba = aIconData->DerefInt32L(KNVG_RGBA_OFS);
       
  1290             lRgba = (lRgba & 0xffffff00)|iStrokeAlpha; // replace alpha
       
  1291             
       
  1292             COND_COM_OC(drawingMode,
       
  1293                     CSICON(iInternal->iCurrentNVGIcon)->AddStrokeSetColorCommandL(lRgba),
       
  1294                     vgSetParameteri( iPaintStroke, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR );
       
  1295                     vgSetColor(iPaintStroke, lRgba));            
       
  1296             break;
       
  1297             }
       
  1298         }
       
  1299     }
       
  1300 
       
  1301 void CNvgEngine::DrawPathL(TDereferencer * aIconData)
       
  1302     {
       
  1303     TInt numSegments = aIconData->DerefInt16L();
       
  1304     const VGubyte * pathSegments  = aIconData->DerefInt8ArrayL(numSegments, sizeof(TUint16));
       
  1305     
       
  1306     /*
       
  1307      * verify that what we got is proper data
       
  1308      * for that calculate the path co-ordinate length
       
  1309      * and check that the path data does not overflow
       
  1310      */    
       
  1311     TInt coordinateCount = 0;
       
  1312     for (TInt i = 0; i < numSegments; ++i)
       
  1313         {
       
  1314         switch (pathSegments[i])
       
  1315             {
       
  1316             case VG_HLINE_TO:
       
  1317             case VG_VLINE_TO:
       
  1318                 coordinateCount += 1;
       
  1319                 break;
       
  1320             case VG_MOVE_TO:
       
  1321             case VG_LINE_TO:
       
  1322             case VG_SQUAD_TO:
       
  1323                 coordinateCount += 2;
       
  1324                 break;                
       
  1325             case VG_QUAD_TO:
       
  1326             case VG_SCUBIC_TO:
       
  1327                 coordinateCount += 4;
       
  1328                 break;
       
  1329             case VG_SCCWARC_TO:
       
  1330             case VG_SCWARC_TO:
       
  1331             case VG_LCCWARC_TO:
       
  1332             case VG_LCWARC_TO:
       
  1333                 coordinateCount += 5;
       
  1334                 break;
       
  1335             case VG_CUBIC_TO:
       
  1336                 coordinateCount += 6;
       
  1337                 break;
       
  1338             default:
       
  1339                 break;
       
  1340             }
       
  1341         }
       
  1342 
       
  1343     // this one is just to check the alignment
       
  1344     TUint8* pathData = aIconData->DerefInt8ArrayL(sizeof(TUint32), sizeof(TUint16) + numSegments);
       
  1345     
       
  1346     /*
       
  1347      * path data need to be word aligned
       
  1348      * alignment are done according to the path format
       
  1349      */
       
  1350     TUint sizeofpathdata = sizeof(TUint32);
       
  1351     TUint alignSkip = 0;
       
  1352     TUint8 * alignedPtr = 0;
       
  1353     if (iLastPathDataType == ESixteenBitEncoding)
       
  1354         {
       
  1355         alignedPtr = Align2(pathData);
       
  1356         sizeofpathdata = sizeof(TUint16);
       
  1357         }
       
  1358     else if (iLastPathDataType == EThirtyTwoBitEncoding)
       
  1359         {        
       
  1360         alignedPtr = Align4(pathData);
       
  1361         }
       
  1362     else
       
  1363         {
       
  1364         User::Leave(KErrCorrupt); // no other path data type is supported
       
  1365         }
       
  1366     
       
  1367     alignSkip = alignedPtr - pathData; 
       
  1368     
       
  1369     /*
       
  1370      * check to see whether we have enough path data
       
  1371      */
       
  1372     aIconData->IsSafeL(coordinateCount * sizeofpathdata + alignSkip, sizeof(TUint16) + numSegments);
       
  1373     
       
  1374     pathData = alignedPtr;
       
  1375     
       
  1376     VGint paintMode = (idoFill ? VG_FILL_PATH : 0)|(idoStroke ? VG_STROKE_PATH : 0);
       
  1377     if (paintMode == 0)
       
  1378         {
       
  1379         paintMode = VG_FILL_PATH;
       
  1380         }
       
  1381     
       
  1382     COND_COM_OC(iInternal->iCreatingNVGIcon,
       
  1383             {
       
  1384                 VGPath path = CreatePath();
       
  1385                 
       
  1386                 if (path != VG_INVALID_HANDLE)
       
  1387                     {
       
  1388                     vgAppendPathData(path, numSegments, pathSegments, pathData);
       
  1389                     }
       
  1390                 else
       
  1391                     {
       
  1392                     CSICON(iInternal->iCurrentNVGIcon)->AddPathDataL(numSegments, pathSegments, pathData);
       
  1393                     }        
       
  1394                 CSICON(iInternal->iCurrentNVGIcon)->AddDrawPathCommandL(path, paintMode);
       
  1395             }, 
       
  1396             {
       
  1397                 vgClearPath(iPath, VG_PATH_CAPABILITY_APPEND_TO);
       
  1398                 
       
  1399                 vgAppendPathData(iPath, numSegments, pathSegments, pathData);
       
  1400                 vgDrawPath(iPath, paintMode);
       
  1401             });
       
  1402     
       
  1403     idoStroke   = VG_FALSE;
       
  1404     idoFill     = VG_FALSE;
       
  1405     }
       
  1406 
       
  1407 #ifdef    OPENVG_OBJECT_CACHING
       
  1408 VGPath CNvgEngine::CreatePath()
       
  1409     {
       
  1410     VGPath path = VG_INVALID_HANDLE;
       
  1411     switch (iLastPathDataType)
       
  1412         {
       
  1413         case EEightBitEncoding:
       
  1414             {
       
  1415             path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
       
  1416             VG_PATH_DATATYPE_S_16, 1.0f/2.0f, 0.0f, 0, 0,
       
  1417             VG_PATH_CAPABILITY_APPEND_TO);           
       
  1418             }
       
  1419             break;
       
  1420             
       
  1421         case ESixteenBitEncoding:
       
  1422             {
       
  1423             path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
       
  1424             VG_PATH_DATATYPE_S_16, 1.0f/16.0f, 0.0f, 0, 0,
       
  1425             VG_PATH_CAPABILITY_APPEND_TO);            
       
  1426             }
       
  1427             break;
       
  1428            
       
  1429         case EThirtyTwoBitEncoding:
       
  1430             {
       
  1431             path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
       
  1432             VG_PATH_DATATYPE_S_32, 1.0f/65536.0f, 0.0f, 0, 0,
       
  1433             VG_PATH_CAPABILITY_APPEND_TO);            
       
  1434             }
       
  1435             break;
       
  1436     
       
  1437         default:
       
  1438             {
       
  1439         
       
  1440             }
       
  1441            break;
       
  1442            }
       
  1443     return path;
       
  1444     }
       
  1445 #endif
       
  1446 
       
  1447 void CNvgEngine::SetTransformL(TDereferencer * aIconData, TUint32 & aCounter, const VGfloat* aCurrentMatrix)
       
  1448     {
       
  1449     
       
  1450     COND_COM_OC(iInternal->iCreatingNVGIcon, ;,
       
  1451              vgLoadMatrix(aCurrentMatrix));
       
  1452     
       
  1453     TUint32 lCommonData    = aIconData->DerefInt32L();
       
  1454     TUint32 lTransformType = (lCommonData & 0x00ff0000)>>16 ;
       
  1455     
       
  1456     VGfloat matrixTemp[9] = {
       
  1457             1.0f, 0.0f, 0.0f,
       
  1458             0.0f, 1.0f, 0.0f,
       
  1459             0.0f, 0.0f, 1.0f };   
       
  1460     
       
  1461     aCounter = 0;
       
  1462     
       
  1463     if (lTransformType != 1)
       
  1464         {
       
  1465         if (lTransformType == KTRANSFORM_COMPLETE)
       
  1466             {
       
  1467             matrixTemp[0] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1468             matrixTemp[4] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1469             matrixTemp[3] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1470             matrixTemp[1] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1471             matrixTemp[6] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1472             matrixTemp[7] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1473             }
       
  1474         else
       
  1475             {
       
  1476             if (lTransformType & KTRANSFORM_ROTATION)
       
  1477                 {
       
  1478                 //vgScale
       
  1479                 matrixTemp[0] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1480                 matrixTemp[4] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1481                 
       
  1482                 //vgShear
       
  1483                 matrixTemp[3] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1484                 matrixTemp[1] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1485                 }
       
  1486             else
       
  1487                 {
       
  1488                 if (lTransformType & KTRANSFORM_SCALING)
       
  1489                     {
       
  1490                     //vgScale
       
  1491                     matrixTemp[0] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1492                     matrixTemp[4] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1493                     }
       
  1494                 
       
  1495                 if (lTransformType & KTRANSFORM_SHEARING)
       
  1496                     {
       
  1497                     //vgShear
       
  1498                     matrixTemp[3] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1499                     matrixTemp[1] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1500                     }
       
  1501                 }
       
  1502             
       
  1503             if (lTransformType & KTRANSFORM_TRANSLATION)
       
  1504                 {
       
  1505                 //vgTranslate
       
  1506                 matrixTemp[6] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1507                 matrixTemp[7] = aIconData->DerefReal32L((++aCounter) * sizeof (VGfloat));
       
  1508                 }
       
  1509             }
       
  1510         
       
  1511         COND_COM_OC(iInternal->iCreatingNVGIcon,
       
  1512                 CSICON(iInternal->iCurrentNVGIcon)->AddSetTransformCommandL(matrixTemp, 1),
       
  1513                 vgMultMatrix(matrixTemp));        
       
  1514         }
       
  1515     else
       
  1516         {
       
  1517         COND_COM_OC(iInternal->iCreatingNVGIcon,
       
  1518                 CSICON(iInternal->iCurrentNVGIcon)->AddSetTransformCommandL(matrixTemp, 0), ;);
       
  1519         }
       
  1520     }
       
  1521 
       
  1522 void CNvgEngine::GenerateMask(CFbsBitmap* aMask)
       
  1523     {
       
  1524     if (!aMask || aMask->SizeInPixels() != iCurrentBufferSize)
       
  1525         {
       
  1526         return;
       
  1527         }
       
  1528     
       
  1529     const TDisplayMode KMaskDisplayMode = aMask->DisplayMode();
       
  1530     
       
  1531     if (KMaskDisplayMode != EGray256 && KMaskDisplayMode != EGray2)
       
  1532         {
       
  1533         return;
       
  1534         }
       
  1535     
       
  1536     const TInt KOriginalFilterMasks = vgGeti(VG_FILTER_CHANNEL_MASK);
       
  1537     const TInt KStride = CFbsBitmap::ScanLineLength(iCurrentBufferSize.iWidth, KMaskDisplayMode);
       
  1538     
       
  1539     // Change to get alpha values from OpenVG
       
  1540     vgSeti(VG_FILTER_CHANNEL_MASK, VG_ALPHA);
       
  1541     
       
  1542     VGImageFormat format = (KMaskDisplayMode == EGray256) ? VG_A_8 : VG_BW_1;
       
  1543     
       
  1544     aMask->LockHeap();
       
  1545 
       
  1546     /*
       
  1547      * Get data address of last line and move upwards (negative stride)
       
  1548      * OpenVG uses Cartesian coordinate system and Symbian uses Screen coordinate system.
       
  1549      */
       
  1550     TUint* data = (TUint*)((TUint)aMask->DataAddress() + (KStride * (iCurrentBufferSize.iHeight - 1 )));
       
  1551     
       
  1552     vgReadPixels(data, -KStride, format, 0, 0,
       
  1553             iCurrentBufferSize.iWidth, iCurrentBufferSize.iHeight);
       
  1554     aMask->UnlockHeap();
       
  1555     
       
  1556     // Set back the original filter-masks
       
  1557     vgSeti(VG_FILTER_CHANNEL_MASK, KOriginalFilterMasks);
       
  1558     }
       
  1559 
       
  1560 void CNvgEngine::ClearBackground()
       
  1561     {
       
  1562     TUint32 rgba = (iBackgroundColor << 8) | (iBackgroundColor >> 24);
       
  1563     TInt32 r, g, b, a;
       
  1564     r = (TInt)((rgba & 0xFF000000) >> 24);
       
  1565     g = (TInt)((rgba & 0x00FF0000) >> 16);
       
  1566     b = (TInt)((rgba & 0x0000FF00) >> 8);
       
  1567     a = (TInt)(rgba & 0x000000FF);
       
  1568     
       
  1569     r += r >> 7; g += g >> 7; b += b >> 7; a += a >> 7;
       
  1570     
       
  1571     const VGfloat KInverse255 =  1.0f/256.0f;
       
  1572     const VGfloat clearColor[4] = { (KInverse255 * VGfloat (r)),
       
  1573             (KInverse255 * VGfloat (g)),
       
  1574             (KInverse255 * VGfloat (b)),
       
  1575             (KInverse255 * VGfloat (a)) };
       
  1576     
       
  1577     vgSeti(VG_SCISSORING, VG_FALSE);
       
  1578     vgSetfv(VG_CLEAR_COLOR, 4, clearColor);
       
  1579     vgClear(0, 0, iCurrentBufferSize.iWidth, iCurrentBufferSize.iHeight);
       
  1580     vgSeti(VG_SCISSORING, VG_TRUE);
       
  1581     }
       
  1582 
       
  1583 TBool CNvgEngine::IsIdentity(VGfloat array[])
       
  1584     {
       
  1585     return ((array[0] == 1.0f && array[4] == 1.0f && array[8] == 1.0f)&& 
       
  1586             (array[1] == 0.0f && array[2] == 0.0f && array[3] == 0.0f &&
       
  1587              array[5] == 0.0f && array[6] == 0.0f && array[7] == 0.0f));
       
  1588     }
       
  1589 
       
  1590 TInt CNvgEngine::OpenVGErrorToSymbianError( TInt aError )
       
  1591     {
       
  1592     TInt error = KErrNone;
       
  1593     switch (aError)
       
  1594         {            
       
  1595         case VGU_OUT_OF_MEMORY_ERROR:
       
  1596         case VG_OUT_OF_MEMORY_ERROR:
       
  1597             {
       
  1598             error = KErrNoMemory;   
       
  1599             break;
       
  1600             }
       
  1601             
       
  1602         case VG_ILLEGAL_ARGUMENT_ERROR:
       
  1603         case VGU_ILLEGAL_ARGUMENT_ERROR:
       
  1604             {
       
  1605             error = KErrArgument; 
       
  1606             break;
       
  1607             }
       
  1608             
       
  1609         case VG_UNSUPPORTED_PATH_FORMAT_ERROR:
       
  1610         case VG_UNSUPPORTED_IMAGE_FORMAT_ERROR:
       
  1611             {
       
  1612             error = KErrNotSupported; 
       
  1613             break;
       
  1614             }
       
  1615             
       
  1616         case VG_IMAGE_IN_USE_ERROR:
       
  1617             {
       
  1618             error = KErrInUse; 
       
  1619             break;
       
  1620             }
       
  1621             
       
  1622         case VG_BAD_HANDLE_ERROR:
       
  1623         case VGU_BAD_HANDLE_ERROR:
       
  1624             {
       
  1625             error = KErrBadHandle;
       
  1626             break;
       
  1627             }
       
  1628             
       
  1629         case VG_PATH_CAPABILITY_ERROR:
       
  1630         case VGU_PATH_CAPABILITY_ERROR:
       
  1631         case VGU_BAD_WARP_ERROR:
       
  1632             {
       
  1633             error = KErrUnknown;
       
  1634             break;
       
  1635             }
       
  1636             
       
  1637         case VG_NO_CONTEXT_ERROR:
       
  1638             {
       
  1639             error = KErrNotReady;
       
  1640             break;
       
  1641             }
       
  1642         
       
  1643         default:
       
  1644             {
       
  1645             error = KErrUnknown; 
       
  1646             }
       
  1647         }
       
  1648     
       
  1649     return error;
       
  1650     }
       
  1651 
       
  1652 void CNvgEngine::UpdateClientMatrices()
       
  1653     {
       
  1654     iMatrixMode = vgGeti(VG_MATRIX_MODE);
       
  1655     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1656     vgGetMatrix(iPathMatrix);
       
  1657     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  1658     vgGetMatrix(iImageMatrix);
       
  1659     vgSeti(VG_MATRIX_MODE, iMatrixMode);
       
  1660     }
       
  1661 
       
  1662 void CNvgEngine::RestoreClientMatrices()
       
  1663     {
       
  1664     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
  1665     vgLoadMatrix(iPathMatrix);
       
  1666     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
  1667     vgLoadMatrix(iImageMatrix);
       
  1668     vgSeti(VG_MATRIX_MODE, iMatrixMode);
       
  1669     }   
       
  1670     
       
  1671 TPoint CNvgEngine::GetTranslatedPoint(VGfloat aTRMatrix[9], TPoint aPoint)
       
  1672     {
       
  1673     TPoint trPoint;
       
  1674     
       
  1675     trPoint.iX = aTRMatrix[0] * aPoint.iX + aTRMatrix[3] * aPoint.iY + aTRMatrix[6];
       
  1676     trPoint.iY = aTRMatrix[1] * aPoint.iX + aTRMatrix[4] * aPoint.iY + aTRMatrix[7];
       
  1677     
       
  1678     return trPoint;
       
  1679     }
       
  1680 
       
  1681 VGfloat CNvgEngine::MinVal4(VGfloat x1, VGfloat x2, VGfloat x3, VGfloat x4 )
       
  1682     {
       
  1683     VGfloat min = x1;
       
  1684     
       
  1685     if (min > x2)
       
  1686         {
       
  1687         min = x2;
       
  1688         }
       
  1689     if (min > x3)
       
  1690         {
       
  1691         min = x3;
       
  1692         }
       
  1693     if (min > x4)
       
  1694         {
       
  1695         min = x4;
       
  1696         }
       
  1697     
       
  1698     return min;
       
  1699     }
       
  1700 
       
  1701 VGfloat CNvgEngine::MaxVal4(VGfloat x1, VGfloat x2, VGfloat x3, VGfloat x4 )
       
  1702     {
       
  1703     VGfloat max = x1;
       
  1704     
       
  1705     if (max < x2)
       
  1706         {
       
  1707         max = x2;
       
  1708         }
       
  1709     if (max < x3)
       
  1710         {
       
  1711         max = x3;
       
  1712         }
       
  1713     if (max < x4)
       
  1714         {
       
  1715         max = x4;
       
  1716         }
       
  1717     
       
  1718     return max;
       
  1719     }
       
  1720