SHResourceType shGetResourceType(VGContext *c, VGHandle h) { if (shIsValidPath(c, h)) return SH_RESOURCE_PATH; else if (shIsValidPaint(c, h)) return SH_RESOURCE_PAINT; else if (shIsValidImage(c, h)) return SH_RESOURCE_IMAGE; else return SH_RESOURCE_INVALID; }
VG_API_CALL void vgDrawPath(VGPath path, VGbitfield paintModes) { SHPath *p; SHMatrix3x3 mi; SHfloat mgl[16]; SHPaint *fill, *stroke; SHRectangle *rect; VG_GETCONTEXT(VG_NO_RETVAL); VG_RETURN_ERR_IF(!shIsValidPath(context, path), VG_BAD_HANDLE_ERROR, VG_NO_RETVAL); VG_RETURN_ERR_IF(paintModes & (~(VG_STROKE_PATH | VG_FILL_PATH)), VG_ILLEGAL_ARGUMENT_ERROR, VG_NO_RETVAL); /* Check whether scissoring is enabled and scissor rectangle is valid */ if (context->scissoring == VG_TRUE) { rect = &context->scissor.items[0]; if (context->scissor.size == 0) VG_RETURN( VG_NO_RETVAL ); if (rect->w <= 0.0f || rect->h <= 0.0f) VG_RETURN( VG_NO_RETVAL ); glScissor( (GLint)rect->x, (GLint)rect->y, (GLint)rect->w, (GLint)rect->h ); glEnable( GL_SCISSOR_TEST ); } p = (SHPath*)path; /* If user-to-surface matrix invertible tessellate in surface space for better path resolution */ if (shIsTessCacheValid( context, p ) == VG_FALSE) { if (shInvertMatrix(&context->pathTransform, &mi)) { shFlattenPath(p, 1); shTransformVertices(&mi, p); }else shFlattenPath(p, 0); shFindBoundbox(p); } /* TODO: Turn antialiasing on/off */ glDisable(GL_LINE_SMOOTH); glDisable(GL_POLYGON_SMOOTH); glEnable(GL_MULTISAMPLE); /* Pick paint if available or default*/ fill = (context->fillPaint ? context->fillPaint : &context->defaultPaint); stroke = (context->strokePaint ? context->strokePaint : &context->defaultPaint); /* Apply transformation */ shMatrixToGL(&context->pathTransform, mgl); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(mgl); if (paintModes & VG_FILL_PATH) { /* Tesselate into stencil */ glEnable(GL_STENCIL_TEST); /* Clear the stencil buffer first */ glStencilFunc(GL_ALWAYS, 0, 0); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); shDrawBoundBox(context, p, VG_FILL_PATH); glStencilFunc(GL_ALWAYS, 0, 0); glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); shDrawVertices(p, GL_TRIANGLE_FAN); /* Setup blending */ updateBlendingStateGL(context, fill->type == VG_PAINT_TYPE_COLOR && fill->color.a == 1.0f); /* Draw paint where stencil odd */ glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); shDrawPaintMesh(context, &p->min, &p->max, VG_FILL_PATH, GL_TEXTURE0); /* Reset state */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); } /* TODO: Turn antialiasing on/off */ glDisable(GL_LINE_SMOOTH); glDisable(GL_POLYGON_SMOOTH); glEnable(GL_MULTISAMPLE); if ((paintModes & VG_STROKE_PATH) && context->strokeLineWidth > 0.0f) { if (1) {/*context->strokeLineWidth > 1.0f) {*/ if (shIsStrokeCacheValid( context, p ) == VG_FALSE) { /* Generate stroke triangles in user space */ shVector2ArrayClear(&p->stroke); shStrokePath(context, p); } /* Stroke into stencil */ glEnable(GL_STENCIL_TEST); /* Clear the stencil buffer first */ glStencilFunc(GL_ALWAYS, 0, 0); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); shDrawBoundBox(context, p, VG_STROKE_PATH); glStencilFunc(GL_NOTEQUAL, 1, 1); glStencilOp(GL_KEEP, GL_INCR, GL_INCR); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); shDrawStroke(p); /* Setup blending */ updateBlendingStateGL(context, stroke->type == VG_PAINT_TYPE_COLOR && stroke->color.a == 1.0f); /* Draw paint where stencil odd */ glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); shDrawPaintMesh(context, &p->min, &p->max, VG_STROKE_PATH, GL_TEXTURE0); /* Reset state */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); }else{ /* Simulate thin stroke by alpha */ SHColor c = stroke->color; if (context->strokeLineWidth < 1.0f) c.a *= context->strokeLineWidth; /* Draw contour as a line */ glDisable(GL_MULTISAMPLE); glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4fv((GLfloat*)&c); shDrawVertices(p, GL_LINE_STRIP); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } } glDisable(GL_MULTISAMPLE); glPopMatrix(); if (context->scissoring == VG_TRUE) glDisable( GL_SCISSOR_TEST ); VG_RETURN(VG_NO_RETVAL); }