/******************************************************************************* * Function Name : DoScaleCentered * Description : Demonstrate the effect of scaling from the centre of a * shape. Each path is transformed separately. *******************************************************************************/ void CTransforms::DoScaleCentered() { // 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 periodic triangle function int i32Zigzag = m_ui32AbsTime % 2000; if(i32Zigzag > 1000) i32Zigzag = 2000 - i32Zigzag; float fScaleFactor = 0.5f + (i32Zigzag * 0.001f); // 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); vgScale(fScaleFactor, fScaleFactor); 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 fScaleFactor = 2 - fScaleFactor; vgTranslate(0.5f, 0.25f); vgScale(fScaleFactor, fScaleFactor); vgTranslate(-0.5f, -0.25f); // draw second path vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH); }
/******************************************************************************* * 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); }
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 ); }
// 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); }
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); }
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; }