void OpenVG_SVGHandler::draw() { vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); // clear out the transform stack _transform_stack.clear(); float m[9]; vgGetMatrix( m ); // assume the current openvg matrix is like the camera matrix and should always be applied first Transform2d top; Transform2d::multiply( top, Transform2d(m), rootTransform() ); // multiply by the root transform pushTransform( top ); // SVG is origin at the top, left (openvg is origin at the bottom, left) // so need to flip // Transform2d flip; // flip.setScale( 1, -1 ); // pushTransform( flip ); if( _batch ) { vgLoadMatrix( topTransform().m ); vgDrawBatchMNK( _batch ); } else { draw_recursive( _root_group ); } vgLoadMatrix( m ); // restore matrix _transform_stack.clear(); }
// Text renders a string of text at a specified location, size, using the specified font glyphs // derived from http://web.archive.org/web/20070808195131/http://developer.hybrid.fi/font2openvg/renderFont.cpp.txt void Text(VGfloat x, VGfloat y, const char *s, Fontinfo f, int pointsize) { VGfloat size = (VGfloat) pointsize, xx = x, mm[9]; vgGetMatrix(mm); int character; unsigned char *ss = (unsigned char *)s; while ((ss = next_utf8_char(ss, &character)) != NULL) { int glyph = f.CharacterMap[character]; if (character >= MAXFONTPATH-1) { continue; } if (glyph == -1) { continue; //glyph is undefined } VGfloat mat[9] = { size, 0.0f, 0.0f, 0.0f, size, 0.0f, xx, y, 1.0f }; vgLoadMatrix(mm); vgMultMatrix(mat); vgDrawPath(f.Glyphs[glyph], VG_FILL_PATH); xx += size * f.GlyphAdvances[glyph] / 65536.0f; } vgLoadMatrix(mm); }
void HbNvgEnginePrivate::restoreClientMatrices() { vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); vgLoadMatrix(mPathMatrix); vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); vgLoadMatrix(mImageMatrix); vgSeti(VG_MATRIX_MODE, mMatrixMode); }
void CNVGCSIcon::RestoreClientMatrices() { vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); vgLoadMatrix(iPathMatrix); vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); vgLoadMatrix(iImageMatrix); vgSeti(VG_MATRIX_MODE, iMatrixMode); }
static bool rpi_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) { rpi_t *rpi = (rpi_t*)data; if (width != rpi->mRenderWidth || height != rpi->mRenderHeight) { rpi->mRenderWidth = width; rpi->mRenderHeight = height; rpi_calculate_quad(rpi); vguComputeWarpQuadToQuad( rpi->x1, rpi->y1, rpi->x2, rpi->y1, rpi->x2, rpi->y2, rpi->x1, rpi->y2, // needs to be flipped, Khronos loves their bottom-left origin 0, height, width, height, width, 0, 0, 0, rpi->mTransformMatrix); vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); vgLoadMatrix(rpi->mTransformMatrix); } vgSeti(VG_SCISSORING, VG_FALSE); vgClear(0, 0, rpi->mScreenWidth, rpi->mScreenHeight); vgSeti(VG_SCISSORING, VG_TRUE); vgImageSubData(rpi->mImage, frame, pitch, rpi->mTexType, 0, 0, width, height); vgDrawImage(rpi->mImage); #ifdef HAVE_FREETYPE if (msg && rpi->mFontsOn) rpi_draw_message(rpi, msg); #else (void)msg; #endif eglSwapBuffers(rpi->mDisplay, rpi->mSurface); return true; }
/******************************************************************************* * Function Name : DoShearCentered * Description : Demonstrate the effect of shearing centred on a * shape. Each path is transformed separately. *******************************************************************************/ void CTransforms::DoShearCentered() { // Make sure we're operating on the path user-to-surface matrix vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); // Load Identity matrix. This clears all previous transformations vgLoadIdentity(); // To be independent of screen resolution, we need to scale the // coordinates so everything in the range [0, 1] will be visible vgScale((float)PVRShellGet(prefWidth), (float)PVRShellGet(prefHeight)); // Unlike OpenGL, OpenVG does not maintain a matrix stack. So instead of // pushing the current matrix to the stack, we have to store it ourselves float afUnitMatrix[3 * 3]; vgGetMatrix(afUnitMatrix); // turn time(ms) into a clipped periodic triangle function int i32Zigzag1 = m_ui32AbsTime % 2000; if(i32Zigzag1 > 1000) i32Zigzag1 = 2000 - i32Zigzag1; i32Zigzag1 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag1)) - 500; // and again, now with shifted phase int i32Zigzag2 = (m_ui32AbsTime + 500) % 2000; if(i32Zigzag2 > 1000) i32Zigzag2 = 2000 - i32Zigzag2; i32Zigzag2 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag2)) - 500; // Scaling a shape from its center is identical to moving it to the // origin, scaling it there, and moving it back where it was. // // IMPORTANT: // Since OpenVG right-multiplies matrices, you conceptually need to // call the transformation functions in backwards order. vgTranslate(0.5f, 0.75f); vgShear(0.001f * i32Zigzag1, 0); vgTranslate(-0.5f, -0.75f); // draw first path vgDrawPath(m_avgPaths[0], VG_STROKE_PATH | VG_FILL_PATH); // restore the unit matrix ([0, 1] visible) vgLoadMatrix(afUnitMatrix); // transformation for second path vgTranslate(0.5f, 0.25f); vgShear(0.001f * i32Zigzag2, 0); vgTranslate(-0.5f, -0.25f); // draw second path vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH); }
void OpenVG_SVGHandler::draw_recursive( group_t& group ) { // push the group matrix onto the stack pushTransform( group.transform ); vgLoadMatrix( topTransform().m ); for ( list<path_object_t>::iterator it = group.path_objects.begin(); it != group.path_objects.end(); it++ ) { path_object_t& po = *it; uint32_t draw_params = 0; if ( po.fill ) { vgSetPaint( po.fill, VG_FILL_PATH ); draw_params |= VG_FILL_PATH; } if ( po.stroke ) { vgSetPaint( po.stroke, VG_STROKE_PATH ); vgSetf( VG_STROKE_LINE_WIDTH, po.stroke_width ); draw_params |= VG_STROKE_PATH; } if( draw_params == 0 ) { // if no stroke or fill use the default black fill vgSetPaint( _blackBackFill, VG_FILL_PATH ); draw_params |= VG_FILL_PATH; } // set the fill rule vgSeti( VG_FILL_RULE, po.fill_rule ); // trasnform pushTransform( po.transform ); vgLoadMatrix( topTransform().m ); vgDrawPath( po.path, draw_params ); popTransform(); vgLoadMatrix( topTransform().m ); } for ( list<group_t>::iterator it = group.children.begin(); it != group.children.end(); it++ ) { draw_recursive( *it ); } popTransform(); vgLoadMatrix( topTransform().m ); }
static bool vg_frame(void *data, const void *frame, unsigned frame_width, unsigned frame_height, uint64_t frame_count, unsigned pitch, const char *msg) { unsigned width, height; vg_t *vg = (vg_t*)data; static struct retro_perf_counter vg_fr = {0}; static struct retro_perf_counter vg_image = {0}; rarch_perf_init(&vg_fr, "vg_fr"); retro_perf_start(&vg_fr); video_driver_get_size(&width, &height); if (frame_width != vg->mRenderWidth || frame_height != vg->mRenderHeight || vg->should_resize) { vg->mRenderWidth = frame_width; vg->mRenderHeight = frame_height; vg_calculate_quad(vg); matrix_3x3_quad_to_quad( vg->x1, vg->y1, vg->x2, vg->y1, vg->x2, vg->y2, vg->x1, vg->y2, /* needs to be flipped, Khronos loves their bottom-left origin */ 0, frame_height, frame_width, frame_height, frame_width, 0, 0, 0, &vg->mTransformMatrix); vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); vgLoadMatrix(vg->mTransformMatrix.data); vg->should_resize = false; } vgSeti(VG_SCISSORING, VG_FALSE); vgClear(0, 0, width, height); vgSeti(VG_SCISSORING, VG_TRUE); rarch_perf_init(&vg_image, "vg_image"); retro_perf_start(&vg_image); vg_copy_frame(vg, frame, frame_width, frame_height, pitch); retro_perf_stop(&vg_image); vgDrawImage(vg->mImage); #if 0 if (msg && vg->mFontsOn) vg_draw_message(vg, msg); #endif gfx_ctx_update_window_title(vg); retro_perf_stop(&vg_fr); gfx_ctx_swap_buffers(vg); return true; }
void applyTransformationMatrix(PainterOpenVG* painter) { // There are *five* separate transforms that can be applied to OpenVG as of 1.1 // but it is not clear that we need to set them separately. Instead we set them // all right here and let this be a call to essentially set the world transformation! VGMatrix vgMatrix(surfaceTransformationMatrix); const VGfloat* vgFloatArray = vgMatrix.toVGfloat(); vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); vgLoadMatrix(vgFloatArray); ASSERT_VG_NO_ERROR(); vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); vgLoadMatrix(vgFloatArray); ASSERT_VG_NO_ERROR(); #ifdef OPENVG_VERSION_1_1 vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE); vgLoadMatrix(vgFloatArray); ASSERT_VG_NO_ERROR(); #endif }
// Text renders a string of text at a specified location, size, using the specified font glyphs // derived from http://web.archive.org/web/20070808195131/http://developer.hybrid.fi/font2openvg/renderFont.cpp.txt void Text(VGfloat x, VGfloat y, char *s, Fontinfo f, int pointsize) { VGfloat size = (VGfloat) pointsize, xx = x, mm[9]; int i; vgGetMatrix(mm); for (i = 0; i < (int)strlen(s); i++) { unsigned int character = (unsigned int)s[i]; int glyph = f.CharacterMap[character]; if (glyph == -1) { continue; //glyph is undefined } VGfloat mat[9] = { size, 0.0f, 0.0f, 0.0f, size, 0.0f, xx, y, 1.0f }; vgLoadMatrix(mm); vgMultMatrix(mat); vgDrawPath(f.Glyphs[glyph], VG_FILL_PATH); xx += size * f.GlyphAdvances[glyph] / 65536.0f; } vgLoadMatrix(mm); }
/******************************************************************************* * Function Name : DoTranslate * Description : Demonstrate the effect of translations. Each path is * translated separately *******************************************************************************/ void CTransforms::DoTranslate() { // Make sure we're operating on the path user-to-surface matrix vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); // Load Identity matrix. This clears all previous transformations vgLoadIdentity(); // To be independent of screen resolution, we need to scale the // coordinates so everything in the range [0, 1] will be visible vgScale((float) PVRShellGet(prefWidth), (float) PVRShellGet(prefHeight)); // Unlike OpenGL, OpenVG does not maintain a matrix stack. So instead of // pushing the current matrix to the stack, we have to store it ourselves float afUnitMatrix[3 * 3]; vgGetMatrix(afUnitMatrix); // turn time(ms) into a clipped periodic triangle function int i32Zigzag1 = m_ui32AbsTime % 2000; if(i32Zigzag1 > 1000) i32Zigzag1 = 2000 - i32Zigzag1; i32Zigzag1 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag1)) - 500; // and again, now with shifted phase int i32Zigzag2 = (m_ui32AbsTime + 500) % 2000; if(i32Zigzag2 > 1000) i32Zigzag2 = 2000 - i32Zigzag2; i32Zigzag2 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag2)) - 250; // translation for first path vgTranslate(-0.001f * i32Zigzag1, -0.001f * i32Zigzag2); // draw first path vgDrawPath(m_avgPaths[0], VG_STROKE_PATH | VG_FILL_PATH); // restore the unit matrix ([0, 1] visible) vgLoadMatrix(afUnitMatrix); // translation for second path vgTranslate(0.001f * i32Zigzag1, 0.001f * i32Zigzag2); // draw second path vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH); }
static bool vg_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) { RARCH_PERFORMANCE_INIT(vg_fr); RARCH_PERFORMANCE_START(vg_fr); vg_t *vg = (vg_t*)data; if (width != vg->mRenderWidth || height != vg->mRenderHeight || vg->should_resize) { vg->mRenderWidth = width; vg->mRenderHeight = height; vg_calculate_quad(vg); matrix_3x3_quad_to_quad( vg->x1, vg->y1, vg->x2, vg->y1, vg->x2, vg->y2, vg->x1, vg->y2, // needs to be flipped, Khronos loves their bottom-left origin 0, height, width, height, width, 0, 0, 0, &vg->mTransformMatrix); vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); vgLoadMatrix(vg->mTransformMatrix.data); vg->should_resize = false; } vgSeti(VG_SCISSORING, VG_FALSE); vgClear(0, 0, vg->mScreenWidth, vg->mScreenHeight); vgSeti(VG_SCISSORING, VG_TRUE); RARCH_PERFORMANCE_INIT(vg_image); RARCH_PERFORMANCE_START(vg_image); vg_copy_frame(vg, frame, width, height, pitch); RARCH_PERFORMANCE_STOP(vg_image); vgDrawImage(vg->mImage); #if 0 if (msg && vg->mFontsOn) vg_draw_message(vg, msg); #endif vg->driver->update_window_title(vg); RARCH_PERFORMANCE_STOP(vg_fr); vg->driver->swap_buffers(vg); return true; }
/******************************************************************************* * Function Name : DoRotateCentered * Description : Demonstrate the effect of rotating around the centre of a * shape. Each path is transformed separately. *******************************************************************************/ void CTransforms::DoRotateCentered() { // Make sure we're operating on the path user-to-surface matrix vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); // Load Identity matrix. This clears all previous transformations vgLoadIdentity(); // To be independent of screen resolution, we need to scale the // coordinates so everything in the range [0, 1] will be visible vgScale((float)PVRShellGet(prefWidth), (float)PVRShellGet(prefHeight)); // Unlike OpenGL, OpenVG does not maintain a matrix stack. So instead of // pushing the current matrix to the stack, we have to store it ourselves float afUnitMatrix[3*3]; vgGetMatrix(afUnitMatrix); float fRotationAngle = m_ui32AbsTime * 0.03f; // Scaling a shape from its center is identical to moving it to the // origin, scaling it there, and moving it back where it was. // // IMPORTANT: // Since OpenVG right-multiplies matrices, you conceptually need to // call the transformation functions in backwards order. vgTranslate(0.5f, 0.75f); vgRotate(fRotationAngle); vgTranslate(-0.5f, -0.75f); // draw first path vgDrawPath(m_avgPaths[0], VG_STROKE_PATH | VG_FILL_PATH); // restore the unit matrix ([0, 1] visible) vgLoadMatrix(afUnitMatrix); // transformation for second path vgTranslate(0.5f, 0.25f); vgRotate(-fRotationAngle); vgTranslate(-0.5f, -0.25f); // draw second path vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH); }
void OpenVG_SVGHandler::optimize() { if( _batch ) { vgDestroyBatchMNK( _batch ); _batch = 0; } // use the monkvg batch extension to greatly optimize rendering. don't need this for // other OpenVG implementations _batch = vgCreateBatchMNK(); vgBeginBatchMNK( _batch ); { // draw // clear out the transform stack _transform_stack.clear(); float m[9]; vgGetMatrix( m ); // assume the current openvg matrix is like the camera matrix and should always be applied first Transform2d top; Transform2d::multiply( top, Transform2d(m), rootTransform() ); // multiply by the root transform pushTransform( top ); // SVG is origin at the top, left (openvg is origin at the bottom, left) // so need to flip // Transform2d flip; // flip.setScale( 1, -1 ); // pushTransform( flip ); draw_recursive( _root_group ); vgLoadMatrix( m ); // restore matrix _transform_stack.clear(); } vgEndBatchMNK( _batch ); }
void OpenVG_SVGHandler::dump(void **vertices, size_t *size) { VGBatchMNK temp; temp = vgCreateBatchMNK(); vgBeginBatchMNK( temp ); { // clear the transform stack _transform_stack.clear(); // save matrix VGfloat m[9]; vgGetMatrix( m ); // assume the current openvg matrix is like the camera matrix and should always be applied first Transform2d top; Transform2d::multiply( top, Transform2d(m), rootTransform() ); // multiply by the root transform pushTransform( top ); // draw draw_recursive( _root_group ); // restore matrix vgLoadMatrix( m ); // clear the transform stack _transform_stack.clear(); } vgDumpBatchMNK( temp, vertices, size ); vgEndBatchMNK( temp ); vgDestroyBatchMNK( temp ); }
void TextWrap(VGfloat x, VGfloat y, char *s, int width, int height, float lineSpacing, Fontinfo f, int pointsize) { VGfloat size = (VGfloat) pointsize, xx = x, yy = y, mm[9]; int i = 0; //float lineSpacing = 0.2; vgGetMatrix(mm); while(i < (int)strlen(s)) { //for (i = 0; i < (int)strlen(s); i++) { if(s[i] == '\n') { // next line xx = x; yy -= size + lineSpacing * size; // + padding i++; if(yy < y - height) // not enough space break; } else { // read word until you hit a space or an \n int wordLength = 0; VGfloat wordSize = 0; if(s[i] == ' ') { wordLength = 1; wordSize = GetWidthOfChar(s[i], f, pointsize); } else { while(i + wordLength < strlen(s) && (s[i+wordLength] != ' ' && s[i+wordLength] != '\n')) { wordLength++; wordSize += GetWidthOfChar(s[i+wordLength], f, pointsize); } } //printf("Word length %d\n", wordLength); //printf("Word: '"); if(xx + wordSize >= x + width) { // next line xx = x; yy -= size + lineSpacing * size; // + padding if(yy < y - height) // not enough space break; } int j; for(j = i; j < i + wordLength; j++) { //printf("%c", s[j]); unsigned int character = (unsigned int)s[j]; int glyph = f.CharacterMap[character]; if (glyph == -1) { continue; //glyph is undefined } VGfloat charSize = GetWidthOfChar(s[j], f, pointsize); if(xx >= x + width + charSize) // letter wrapping { xx = x; yy -= size + lineSpacing * size; if(yy < y - height) // not enough space break; } VGfloat mat[9] = { size, 0.0f, 0.0f, 0.0f, size, 0.0f, xx, yy, 1.0f }; vgLoadMatrix(mm); vgMultMatrix(mat); vgDrawPath(f.Glyphs[glyph], VG_FILL_PATH); xx += charSize; } //printf("'\n"); i += wordLength; } } vgLoadMatrix(mm); }
void CNVGCSIcon::DrawPaintL(VGPaint aPaint, VGMatrixMode aMatrixMode, TUint & aLastPaintType, TUint & aLastPaintColor, VGPaintMode aPaintMode) { VGPaintType paintType = (VGPaintType)iNVGIconData->ReadInt32L(); if (paintType == VG_PAINT_TYPE_LINEAR_GRADIENT || paintType == VG_PAINT_TYPE_RADIAL_GRADIENT) { VGPaintParamType paintPType = VG_PAINT_LINEAR_GRADIENT; if (paintType == VG_PAINT_TYPE_RADIAL_GRADIENT) { paintPType = VG_PAINT_RADIAL_GRADIENT; } VGPaint paintHandle = iNVGIconData->ReadInt32L(); TInt count = iNVGIconData->ReadInt32L(); VGfloat gradientData[5]; VGfloat gradientMatrix[9]; iNVGIconData->ReadL((TUint8 *)gradientData, count * sizeof(VGfloat)); iNVGIconData->ReadL((TUint8 *)gradientMatrix, 9 * sizeof(VGfloat)); if (paintHandle) { vgSetPaint(paintHandle, aPaintMode); vgSeti(VG_MATRIX_MODE, aMatrixMode); vgLoadMatrix(gradientMatrix); if (aPaintMode == VG_FILL_PATH) { iResetFillPaint = 1; } else { iResetStrokePaint = 1; } } else { if (aLastPaintType != paintType) { vgSetParameteri(aPaint, VG_PAINT_TYPE, paintType); } vgSetParameterfv(aPaint, paintPType, count, gradientData); vgSeti(VG_MATRIX_MODE, aMatrixMode); vgLoadMatrix(gradientMatrix); } vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); } else if (paintType == VG_PAINT_TYPE_COLOR) { if (aPaintMode == VG_FILL_PATH && iResetFillPaint) { iResetFillPaint = 0; vgSetPaint(aPaint, aPaintMode); } else if (aPaintMode == VG_STROKE_PATH && iResetStrokePaint) { iResetStrokePaint = 0; vgSetPaint(aPaint, aPaintMode); } TUint color = static_cast<TUint>(iNVGIconData->ReadInt32L()); if (aLastPaintType != paintType) { vgSetParameteri(aPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); vgSetColor(aPaint, color); } else { if (aLastPaintColor != color) { vgSetColor(aPaint, color); } } aLastPaintColor = color; } else { User::Leave(KErrCorrupt); } aLastPaintType = paintType; }
TInt CNVGCSIcon::DoDrawL(const TSize aSize) { TInt ret = KErrNone; vgSetPaint(iFillPaint, VG_FILL_PATH); vgSetPaint(iStrokePaint, VG_STROKE_PATH); iLastFillPaintColor = 0; iLastStrkePaintColor = 0; iLastFillPaintType = 0; iLastStrokePaintType = 0; VGfloat lCurrentPathMatrix[9]; vgGetMatrix(lCurrentPathMatrix); vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); vgLoadMatrix(lCurrentPathMatrix); SetRotation(); #ifdef __MIRROR_ vgScale(1.0f, -1.0f); vgTranslate(0, (VGfloat)(-aSize.iHeight) ); #endif SetViewBoxToViewTransformationL(aSize); vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); VGfloat currentMatrix[9]; vgGetMatrix(currentMatrix); iNVGIconData->BeginRead(); while (!iNVGIconData->EOF()) { switch (iNVGIconData->ReadInt32L()) { case EPath: { VGPath path = (VGPath)iNVGIconData->ReadInt32L(); VGPaintMode paintMode = (VGPaintMode)iNVGIconData->ReadInt32L(); if (path == VG_INVALID_HANDLE) { vgDrawPath(iPath, paintMode); } else { vgDrawPath(path, paintMode); } break; } case EPathData: { if (iPath != VG_INVALID_HANDLE) { VGint numSegments; VGubyte * pathSegments = 0; VGubyte * pathData = 0; numSegments = iNVGIconData->ReadInt32L(); pathSegments = new (ELeave) VGubyte[numSegments]; CleanupStack::PushL(TCleanupItem(CleanupArray, pathSegments)); if (pathSegments) { iNVGIconData->ReadL(pathSegments, numSegments); VGint coordinateCount = iNVGIconData->ReadInt32L(); pathData = new (ELeave) VGubyte[coordinateCount * 4]; if (pathData) { CleanupStack::PushL(TCleanupItem(CleanupArray, pathData)); iNVGIconData->ReadL(pathData, coordinateCount * 4); vgClearPath(iPath, VG_PATH_CAPABILITY_APPEND_TO); vgAppendPathData(iPath, numSegments, pathSegments, pathData); CleanupStack::PopAndDestroy(); } } CleanupStack::PopAndDestroy(); } break; } case EPaint: { DrawPaintL(iFillPaint, VG_MATRIX_FILL_PAINT_TO_USER, iLastFillPaintType, iLastFillPaintColor, VG_FILL_PATH); break; } case EColorRamp: { iNVGIconData->ReadInt32L(); break; } case ETransform: { TInt flag; VGfloat transformMatrix[9]; TPtr8 tmPtr((TUint8 *)transformMatrix, 9 * sizeof(VGfloat)); iNVGIconData->ReadL(tmPtr, 9 * sizeof(VGfloat)); flag = iNVGIconData->ReadInt32L(); vgLoadMatrix(currentMatrix); if (flag) { vgMultMatrix(transformMatrix); } } break; case EStrokeWidth: { VGfloat strokeWidth = iNVGIconData->ReadReal32L(); vgSetf(VG_STROKE_LINE_WIDTH, strokeWidth); break; } case EStrokeMiterLimit: { VGfloat miterLimit = iNVGIconData->ReadReal32L(); vgSetf(VG_STROKE_MITER_LIMIT, miterLimit); break; } case EStrokeLineJoinCap: { VGint lineJoin = iNVGIconData->ReadInt32L(); VGint cap = iNVGIconData->ReadInt32L(); vgSeti(VG_STROKE_JOIN_STYLE, (VGJoinStyle)lineJoin); vgSeti(VG_STROKE_CAP_STYLE, (VGCapStyle)cap); break; } case EStrokePaint: { DrawPaintL(iStrokePaint, VG_MATRIX_STROKE_PAINT_TO_USER, iLastStrokePaintType, iLastStrkePaintColor, VG_STROKE_PATH); break; } case EStrokeColorRamp: { iNVGIconData->ReadInt32L(); break; } default: { User::Leave(KErrCorrupt); break; } } } iNVGIconData->EndRead(); return ret; }