// newpath creates path data VGPath newpath() { return vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL); }
PS* PS_construct(const char* commands, int commandCount, const float* points, int pointCount) { PS* ps = (PS*)malloc(sizeof(PS)); int p = 0; int c = 0; int i = 0; int paths = 0; int maxElements = 0; unsigned char* cmd; UNREF(pointCount); while(c < commandCount) { int elements, e; c += 4; p += 8; elements = (int)points[p++]; assert(elements > 0); if(elements > maxElements) maxElements = elements; for(e=0;e<elements;e++) { switch(commands[c]) { case 'M': p += 2; break; case 'L': p += 2; break; case 'C': p += 6; break; case 'E': break; default: assert(0); //unknown command } c++; } paths++; } ps->m_numPaths = paths; ps->m_paths = (PathData*)malloc(paths * sizeof(PathData)); cmd = (unsigned char*)malloc(maxElements); i = 0; p = 0; c = 0; while(c < commandCount) { int elements, startp, e; float color[4]; //fill type int paintMode = 0; ps->m_paths[i].m_fillRule = VG_NON_ZERO; switch( commands[c] ) { case 'N': break; case 'F': ps->m_paths[i].m_fillRule = VG_NON_ZERO; paintMode |= VG_FILL_PATH; break; case 'E': ps->m_paths[i].m_fillRule = VG_EVEN_ODD; paintMode |= VG_FILL_PATH; break; default: assert(0); //unknown command } c++; //stroke switch( commands[c] ) { case 'N': break; case 'S': paintMode |= VG_STROKE_PATH; break; default: assert(0); //unknown command } ps->m_paths[i].m_paintMode = (VGPaintMode)paintMode; c++; //line cap switch( commands[c] ) { case 'B': ps->m_paths[i].m_capStyle = VG_CAP_BUTT; break; case 'R': ps->m_paths[i].m_capStyle = VG_CAP_ROUND; break; case 'S': ps->m_paths[i].m_capStyle = VG_CAP_SQUARE; break; default: assert(0); //unknown command } c++; //line join switch( commands[c] ) { case 'M': ps->m_paths[i].m_joinStyle = VG_JOIN_MITER; break; case 'R': ps->m_paths[i].m_joinStyle = VG_JOIN_ROUND; break; case 'B': ps->m_paths[i].m_joinStyle = VG_JOIN_BEVEL; break; default: assert(0); //unknown command } c++; //the rest of stroke attributes ps->m_paths[i].m_miterLimit = points[p++]; ps->m_paths[i].m_strokeWidth = points[p++]; //paints color[0] = points[p++]; color[1] = points[p++]; color[2] = points[p++]; color[3] = 1.0f; ps->m_paths[i].m_strokePaint = vgCreatePaint(); vgSetParameteri(ps->m_paths[i].m_strokePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); vgSetParameterfv(ps->m_paths[i].m_strokePaint, VG_PAINT_COLOR, 4, color); color[0] = points[p++]; color[1] = points[p++]; color[2] = points[p++]; color[3] = 1.0f; ps->m_paths[i].m_fillPaint = vgCreatePaint(); vgSetParameteri(ps->m_paths[i].m_fillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); vgSetParameterfv(ps->m_paths[i].m_fillPaint, VG_PAINT_COLOR, 4, color); //read number of elements elements = (int)points[p++]; assert(elements > 0); startp = p; for(e=0;e<elements;e++) { switch( commands[c] ) { case 'M': cmd[e] = VG_MOVE_TO | VG_ABSOLUTE; p += 2; break; case 'L': cmd[e] = VG_LINE_TO | VG_ABSOLUTE; p += 2; break; case 'C': cmd[e] = VG_CUBIC_TO | VG_ABSOLUTE; p += 6; break; case 'E': cmd[e] = VG_CLOSE_PATH; break; default: assert(0); //unknown command } c++; } ps->m_paths[i].m_path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, (unsigned int)VG_PATH_CAPABILITY_ALL); vgAppendPathData(ps->m_paths[i].m_path, elements, cmd, points + startp); i++; } free(cmd); return ps; }
void CTSmallWindowOpenVG::ConstructL(RWsSession &aWs, const RWindowTreeNode &aParent) { CTWindow::ConstructL(aWs, aParent); iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(iDisplay, NULL, NULL); EGLint numConfigs; EGLConfig chosenConfig = 0; // Choose the config to use eglChooseConfig(iDisplay, KColorRGB565AttribList, &chosenConfig, 1, &numConfigs); if (numConfigs == 0) { RDebug::Printf("No matching configs found", eglQueryString(iDisplay, EGL_EXTENSIONS)); User::Leave(KErrNotSupported); } // Create window surface to draw direct to. eglBindAPI(EGL_OPENVG_API); iSurface = eglCreateWindowSurface(iDisplay, chosenConfig, &iWindow, NULL); // Create context to store surface settings iContextVG = eglCreateContext(iDisplay, chosenConfig, EGL_NO_CONTEXT, NULL); eglMakeCurrent(iDisplay, iSurface, iSurface, iContextVG); VGfloat strokeColor[4] = {1.f, 0.f, 0.f, 1.f}; VGfloat fillColor[4] = {0.f, 0.f, 1.f, 1.f}; VGubyte pathSegments[6] = { VG_LINE_TO | (int)VG_ABSOLUTE, VG_LINE_TO | (int)VG_ABSOLUTE, VG_LINE_TO | (int)VG_ABSOLUTE, VG_LINE_TO | (int)VG_ABSOLUTE, VG_CLOSE_PATH }; VGfloat pathData[10] = { 0.f, 100.f, 100.f, 100.f, 100.f, 0.f, 0.f, 0.f }; vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); iCurrentRotation = 0.f; iStrokePaint = vgCreatePaint(); iFillPaint = vgCreatePaint(); vgSetParameteri(iStrokePaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); vgSetParameterfv(iStrokePaint, VG_PAINT_COLOR, 4, strokeColor); vgSetParameteri(iFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); vgSetParameterfv(iFillPaint, VG_PAINT_COLOR, 4, fillColor); iPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 4, 4, (unsigned int)VG_PATH_CAPABILITY_ALL); vgAppendPathData(iPath, 4, pathSegments, pathData); }
void PainterOpenVG::drawRoundedRect(const FloatRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, VGbitfield specifiedPaintModes) { ASSERT(m_state); VGbitfield paintModes = 0; if (!m_state->strokeDisabled()) paintModes |= VG_STROKE_PATH; if (!m_state->fillDisabled()) paintModes |= VG_FILL_PATH; paintModes &= specifiedPaintModes; if (!paintModes) return; m_surface->makeCurrent(); VGPath path = vgCreatePath( VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0 /* scale */, 0.0 /* bias */, 10 /* expected number of segments */, 25 /* expected number of total coordinates */, VG_PATH_CAPABILITY_APPEND_TO); ASSERT_VG_NO_ERROR(); // clamp corner arc sizes FloatSize clampedTopLeft = FloatSize(topLeft).shrunkTo(rect.size()).expandedTo(FloatSize()); FloatSize clampedTopRight = FloatSize(topRight).shrunkTo(rect.size()).expandedTo(FloatSize()); FloatSize clampedBottomLeft = FloatSize(bottomLeft).shrunkTo(rect.size()).expandedTo(FloatSize()); FloatSize clampedBottomRight = FloatSize(bottomRight).shrunkTo(rect.size()).expandedTo(FloatSize()); // As OpenVG's coordinate system is flipped in comparison to WebKit's, // we have to specify the opposite value for the "clockwise" value. static const VGubyte pathSegments[] = { VG_MOVE_TO_ABS, VG_HLINE_TO_REL, VG_SCCWARC_TO_REL, VG_VLINE_TO_REL, VG_SCCWARC_TO_REL, VG_HLINE_TO_REL, VG_SCCWARC_TO_REL, VG_VLINE_TO_REL, VG_SCCWARC_TO_REL, VG_CLOSE_PATH }; // Also, the rounded rectangle path proceeds from the top to the bottom, // requiring height distances and clamped radius sizes to be flipped. const VGfloat pathData[] = { rect.x() + clampedTopLeft.width(), rect.y(), rect.width() - clampedTopLeft.width() - clampedTopRight.width(), clampedTopRight.width(), clampedTopRight.height(), 0, clampedTopRight.width(), clampedTopRight.height(), rect.height() - clampedTopRight.height() - clampedBottomRight.height(), clampedBottomRight.width(), clampedBottomRight.height(), 0, -clampedBottomRight.width(), clampedBottomRight.height(), -(rect.width() - clampedBottomLeft.width() - clampedBottomRight.width()), clampedBottomLeft.width(), clampedBottomLeft.height(), 0, -clampedBottomLeft.width(), -clampedBottomLeft.height(), -(rect.height() - clampedTopLeft.height() - clampedBottomLeft.height()), clampedTopLeft.width(), clampedTopLeft.height(), 0, clampedTopLeft.width(), -clampedTopLeft.height(), }; vgAppendPathData(path, 10, pathSegments, pathData); vgDrawPath(path, paintModes); vgDestroyPath(path); ASSERT_VG_NO_ERROR(); }
/*!*************************************************************************** @Function LoadMemoryBuffer @Input pui8DataFile Data Buffer @Input i32FileSize Size of buffer @Returns True on success @Description Process a PVG data block. *****************************************************************************/ bool CPVRTPVGObject::LoadMemoryBuffer(unsigned char* pui8DataFile, int i32FileSize) { vgGetError();//Clear any errors PVG_FILE_HEADER* pFileHeader; struct COLOURRAMP {unsigned int NumStops; float *pfData;} *Ramps; int i32FileOffset = 0; unsigned int ui32; int i32; // Get the file header pFileHeader = (PVG_FILE_HEADER*)pui8DataFile; // Check that this file is a correct one if (pFileHeader->dwMagicToken != 'POVG') { return false; } // Fill dimensions m_fLeft = pFileHeader->fLeft; m_fTop = pFileHeader->fTop; m_fRight = pFileHeader->fRight; m_fBottom = pFileHeader->fBottom; m_fWidth = (float)fabs(m_fRight - m_fLeft); m_fHeight = (float)fabs(m_fBottom - m_fTop); // Increase the file pointer i32FileOffset = sizeof(PVG_FILE_HEADER); // Allocate structures m_i32NumPaths = pFileHeader->dwNumPaths; m_pPaths = (PathData*)malloc(pFileHeader->dwNumPaths * sizeof(PathData)); m_i32NumPaints = pFileHeader->dwNumPaints; m_pPaints = (VGPaint *)malloc(m_i32NumPaints * sizeof(VGPaint)); ////////////////////////////////////////////////////// // Get all colour ramps (if any) // These are stored secuentially after the FileHeader // DWORD NumStops, FLOAT 5*NumStops ////////////////////////////////////////////////////// Ramps = (COLOURRAMP *) malloc (sizeof(COLOURRAMP)*pFileHeader->dwNumRamps); for (ui32=0; ui32<pFileHeader->dwNumRamps; ui32++) { Ramps[ui32].NumStops = *((unsigned int *)(pui8DataFile + i32FileOffset)); i32FileOffset += sizeof(unsigned); Ramps[ui32].pfData = (float *)(pui8DataFile + i32FileOffset); i32FileOffset += Ramps[ui32].NumStops * sizeof(float)*5; } //////////////////////////////////////////////////////// // Get all paints // These are stored secuentially after the colour ramps // PVG_PAINT_HEADER //////////////////////////////////////////////////////// for (i32=0; i32<m_i32NumPaints; i32++) { m_pPaints[i32] = vgCreatePaint(); PVG_PAINT_HEADER *sFilePaintData = (PVG_PAINT_HEADER *)(pui8DataFile + i32FileOffset); vgSetParameteri(m_pPaints[i32], VG_PAINT_TYPE, sFilePaintData->dwPaintStyle); switch (sFilePaintData->dwPaintStyle) { case VG_PAINT_TYPE_LINEAR_GRADIENT: { COLOURRAMP sCurrentRamp = Ramps[sFilePaintData->dwRamp]; vgSetParameterfv(m_pPaints[i32], VG_PAINT_LINEAR_GRADIENT, 4, sFilePaintData->fPaintParameters); vgSetParameteri(m_pPaints[i32], VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD); vgSetParameterfv(m_pPaints[i32], VG_PAINT_COLOR_RAMP_STOPS, sCurrentRamp.NumStops*5, sCurrentRamp.pfData); break; } case VG_PAINT_TYPE_RADIAL_GRADIENT: { COLOURRAMP sCurrentRamp = Ramps[sFilePaintData->dwRamp]; vgSetParameterfv(m_pPaints[i32], VG_PAINT_RADIAL_GRADIENT, 5, sFilePaintData->fPaintParameters); vgSetParameteri(m_pPaints[i32], VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD); vgSetParameterfv(m_pPaints[i32], VG_PAINT_COLOR_RAMP_STOPS, sCurrentRamp.NumStops*5, sCurrentRamp.pfData); break; } case VG_PAINT_TYPE_PATTERN: case VG_PAINT_TYPE_COLOR: default: { vgSetParameteri(m_pPaints[i32], VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); vgSetParameterfv(m_pPaints[i32], VG_PAINT_COLOR, 4, sFilePaintData->fPaintParameters); break; } } if(vgGetError() != VG_NO_ERROR) { // Free ramps list. This is not needed any more free(Ramps); return false; } // Increase the offset to point to the next paint (the size of a paint is the size of the paint header) i32FileOffset += sizeof(PVG_PAINT_HEADER); } // Free ramps list. This is not needed any more free(Ramps); //////////////////////////////////////////////////////// // Get all Paths // These are stored secuentially after the Paints // PVG_PATH_HEADER, BYTE Commands, FLOAT Points //////////////////////////////////////////////////////// for (i32=0; i32<m_i32NumPaths; i32++) { PVG_PATH_HEADER *sFilepathData = (PVG_PATH_HEADER *)(pui8DataFile + i32FileOffset); // Fill structure from file m_pPaths[i32].m_fillRule = (VGFillRule) sFilepathData->dwFillRule; m_pPaths[i32].m_paintMode = (VGPaintMode) sFilepathData->dwPathType; m_pPaths[i32].m_capStyle = (VGCapStyle) sFilepathData->dwStrokeCap; m_pPaths[i32].m_joinStyle = (VGJoinStyle) sFilepathData->dwStrokeJoin; m_pPaths[i32].m_fMiterLimit = sFilepathData->fStrokeMiterLimit; m_pPaths[i32].m_fStrokeWidth = sFilepathData->fStrokeWidth; m_pPaths[i32].m_strokePaint = (m_pPaths[i32].m_paintMode & VG_STROKE_PATH) ? m_pPaints[sFilepathData->StrokePaint] : (VGPaint)NULL; m_pPaths[i32].m_fillPaint = (m_pPaths[i32].m_paintMode & VG_FILL_PATH) ? m_pPaints[sFilepathData->FillPaint] : (VGPaint)NULL; m_pPaths[i32].m_ui32DashID = sFilepathData->StrokeDash; // 666 for none m_pPaths[i32].m_bIsNewFill = (i32==0 || (m_pPaths[i32].m_fillPaint!=m_pPaths[i32-1].m_fillPaint)) ? 1:0; m_pPaths[i32].m_bNeedsBlending = (sFilepathData->dwAlphaBlend) ? 1:0; m_pPaths[i32].m_bIsNewStroke = (i32==0 || (m_pPaths[i32].m_strokePaint!=m_pPaths[i32-1].m_strokePaint) || (m_pPaths[i32].m_ui32DashID!=m_pPaths[i32-1].m_ui32DashID) || (m_pPaths[i32].m_fStrokeWidth!=m_pPaths[i32-1].m_fStrokeWidth)) ? 1 :0; // Create Path m_pPaths[i32].m_path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, (unsigned int)VG_PATH_CAPABILITY_ALL); // Commands (after header) i32FileOffset += sizeof(PVG_PATH_HEADER); VGubyte *pui8Cmd = (VGubyte *)(pui8DataFile + i32FileOffset); // Data (after commands) i32FileOffset += ((sFilepathData->dwNumSegments/4)+1)*4; // Commands size is 1 byte per command/segments and it is 32bits aligned in size float *pfPoints = (float *)(pui8DataFile + i32FileOffset); // Store the path vgAppendPathData(m_pPaths[i32].m_path, sFilepathData->dwNumSegments, pui8Cmd, pfPoints); // Move to the next path i32FileOffset += sFilepathData->dwPathDataSize; // Data size is variable depending of the tipe of segment if(vgGetError() != VG_NO_ERROR) { return false; } } //////////////////////////////////////////////////////// // Get all stroke Dashes // These are stored secuentially after the Paths in the PVG file // In this case we fill in the variables inside our path structure // to be used later, once we are going to draw the path. //////////////////////////////////////////////////////// for (i32=0; i32<m_i32NumPaths; i32++) { unsigned int ui32CurrentDash = m_pPaths[i32].m_ui32DashID; if(ui32CurrentDash != 666 && ui32CurrentDash<pFileHeader->dwNumDashes) // This path does not have a dashed stroke { // Point to the dash float *pMem = (float *)(pui8DataFile + i32FileOffset + ui32CurrentDash*sizeof(PVG_DASH_HEADER)); // Fill in the data m_pPaths[i32].m_ui32NumDashes = *((unsigned int *)pMem++); m_pPaths[i32].m_fDashPhase = *pMem++; for (int i=0; i<6; i++) m_pPaths[i32].m_fDashValues[i] = *pMem++; } else { m_pPaths[i32].m_ui32DashID = 666; // cancel this dash } } // Increase offset i32FileOffset += pFileHeader->dwNumDashes*sizeof(PVG_DASH_HEADER); // Load successful. m_bInitialized = true; return true; }