diff --git a/src/nanovg.c b/src/nanovg.c index ac0f61a..3876357 100644 --- a/src/nanovg.c +++ b/src/nanovg.c @@ -181,7 +181,7 @@ error: static void nvg__setDevicePixelRatio(struct NVGcontext* ctx, float ratio) { - ctx->tessTol = 0.3f * 4.0f / ratio; + ctx->tessTol = 0.25f * 4.0f / ratio; ctx->distTol = 0.01f / ratio; ctx->fringeWidth = 1.0f / ratio; ctx->devicePxRatio = ratio; @@ -1755,7 +1755,7 @@ void nvgFill(struct NVGcontext* ctx) else nvg__expandStrokeAndFill(ctx, NVG_FILL, 0.0f, NVG_BUTT, NVG_MITER, 1.2f); - ctx->params.renderFill(ctx->params.userPtr, &state->fill, &state->scissor, + ctx->params.renderFill(ctx->params.userPtr, &state->fill, &state->scissor, ctx->fringeWidth, ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths); // Count triangles @@ -1777,11 +1777,11 @@ void nvgStroke(struct NVGcontext* ctx) nvg__flattenPaths(ctx); if (ctx->params.edgeAntiAlias) - nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f + ctx->fringeWidth/2.0f, state->lineCap, state->lineJoin, state->miterLimit); + nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f + ctx->fringeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit); else nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit); - ctx->params.renderStroke(ctx->params.userPtr, &state->stroke, &state->scissor, + ctx->params.renderStroke(ctx->params.userPtr, &state->stroke, &state->scissor, ctx->fringeWidth, strokeWidth, ctx->cache->paths, ctx->cache->npaths); // Count triangles diff --git a/src/nanovg.h b/src/nanovg.h index 15be9eb..edb5d9f 100644 --- a/src/nanovg.h +++ b/src/nanovg.h @@ -440,8 +440,8 @@ struct NVGparams { int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); void (*renderViewport)(void* uptr, int width, int height, int alphaBlend); void (*renderFlush)(void* uptr, int alphaBlend); - void (*renderFill)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, const float* bounds, const struct NVGpath* paths, int npaths); - void (*renderStroke)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float strokeWidth, const struct NVGpath* paths, int npaths); + void (*renderFill)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, const float* bounds, const struct NVGpath* paths, int npaths); + void (*renderStroke)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, float strokeWidth, const struct NVGpath* paths, int npaths); void (*renderTriangles)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, const struct NVGvertex* verts, int nverts); void (*renderDelete)(void* uptr); }; diff --git a/src/nanovg_gl2.h b/src/nanovg_gl2.h index 14e2db8..053045c 100644 --- a/src/nanovg_gl2.h +++ b/src/nanovg_gl2.h @@ -560,7 +560,7 @@ static void glnvg__xformToMat3x3(float* m3, float* t) m3[8] = 1.0f; } -static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, struct NVGscissor* scissor, float width) +static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, struct NVGscissor* scissor, float width, float fringe) { float innerCol[4]; float outerCol[4]; @@ -586,8 +586,8 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st glnvg__xformToMat3x3(scissorMat, invxform); scissorx = scissor->extent[0]; scissory = scissor->extent[1]; - scissorsx = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]); - scissorsy = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]); + scissorsx = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]) / fringe; + scissorsy = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]) / fringe; } if (paint->image != 0) { @@ -601,7 +601,7 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], scissorsx, scissorsy); glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, paintMat); glUniform2f(gl->shader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]); - glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + 0.5f); + glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], (width*0.5f + fringe*0.5f)/fringe); glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0); glUniform1i(gl->shader.loc[GLNVG_LOC_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); glnvg__checkError("tex paint loc"); @@ -620,7 +620,7 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st glUniform1f(gl->shader.loc[GLNVG_LOC_FEATHER], paint->feather); glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, innerCol); glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol); - glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + 0.5f); + glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], (width*0.5f + fringe*0.5f)/fringe); glnvg__checkError("grad paint loc"); } return 1; @@ -673,7 +673,7 @@ static void glnvg__uploadPaths(const struct NVGpath* paths, int npaths) } } -static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, +static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, const float* bounds, const struct NVGpath* paths, int npaths) { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; @@ -694,7 +694,7 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); - glnvg__setupPaint(gl, paint, scissor, 1.0001f); + glnvg__setupPaint(gl, paint, scissor, fringe, fringe); glDisable(GL_CULL_FACE); n = 0; @@ -769,7 +769,7 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis glEnable(GL_BLEND); glEnableVertexAttribArray(1); - glnvg__setupPaint(gl, paint, scissor, 1.0001f); + glnvg__setupPaint(gl, paint, scissor, fringe, fringe); if (gl->edgeAntiAlias) { glStencilFunc(GL_EQUAL, 0x00, 0xff); @@ -806,7 +806,7 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis } } -static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, +static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, float width, const struct NVGpath* paths, int npaths) { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; @@ -816,7 +816,7 @@ static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGsc if (gl->shader.prog == 0) return; - glnvg__setupPaint(gl, paint, scissor, width); + glnvg__setupPaint(gl, paint, scissor, width, fringe); glEnable(GL_CULL_FACE); diff --git a/src/nanovg_gl3.h b/src/nanovg_gl3.h index 233aad6..56b692b 100644 --- a/src/nanovg_gl3.h +++ b/src/nanovg_gl3.h @@ -566,7 +566,7 @@ static void glnvg__xformToMat3x3(float* m3, float* t) m3[8] = 1.0f; } -static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, struct NVGscissor* scissor, float width) +static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, struct NVGscissor* scissor, float width, float fringe) { float innerCol[4]; float outerCol[4]; @@ -592,8 +592,8 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st glnvg__xformToMat3x3(scissorMat, invxform); scissorx = scissor->extent[0]; scissory = scissor->extent[1]; - scissorsx = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]); - scissorsy = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]); + scissorsx = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]) / fringe; + scissorsy = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]) / fringe; } if (paint->image != 0) { @@ -607,7 +607,7 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st glUniform2f(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], scissorsx, scissorsy); glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, paintMat); glUniform2f(gl->shader.loc[GLNVG_LOC_EXTENT], paint->extent[0], paint->extent[1]); - glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + 0.5f); + glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], (width*0.5f + fringe*0.5f)/fringe); glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0); glUniform1i(gl->shader.loc[GLNVG_LOC_TEXTYPE], tex->type == NVG_TEXTURE_RGBA ? 0 : 1); glnvg__checkError("tex paint loc"); @@ -626,7 +626,7 @@ static int glnvg__setupPaint(struct GLNVGcontext* gl, struct NVGpaint* paint, st glUniform1f(gl->shader.loc[GLNVG_LOC_FEATHER], paint->feather); glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, innerCol); glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, outerCol); - glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], width*0.5f + 0.5f); + glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], (width*0.5f + fringe*0.5f)/fringe); glnvg__checkError("grad paint loc"); } return 1; @@ -648,6 +648,7 @@ static void glnvg__renderFlush(void* uptr, int alphaBlend) { // struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; NVG_NOTUSED(uptr); + NVG_NOTUSED(alphaBlend); } static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths) @@ -677,7 +678,7 @@ static void glnvg__uploadPaths(const struct NVGpath* paths, int npaths) } } -static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, +static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, const float* bounds, const struct NVGpath* paths, int npaths) { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; @@ -699,7 +700,7 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); - glnvg__setupPaint(gl, paint, scissor, 1.0001f); + glnvg__setupPaint(gl, paint, scissor, fringe, fringe); glDisable(GL_CULL_FACE); n = 0; @@ -771,7 +772,7 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis glEnable(GL_BLEND); glEnableVertexAttribArray(1); - glnvg__setupPaint(gl, paint, scissor, 1.0001f); + glnvg__setupPaint(gl, paint, scissor, fringe, fringe); if (gl->edgeAntiAlias) { glStencilFunc(GL_EQUAL, 0x00, 0xff); @@ -812,7 +813,7 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis } } -static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, +static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, float width, const struct NVGpath* paths, int npaths) { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; @@ -822,7 +823,7 @@ static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGsc if (gl->shader.prog == 0) return; - glnvg__setupPaint(gl, paint, scissor, width); + glnvg__setupPaint(gl, paint, scissor, width, fringe); glEnable(GL_CULL_FACE); diff --git a/src/nanovg_gl3buf.h b/src/nanovg_gl3buf.h index ca70df2..0d1e52f 100644 --- a/src/nanovg_gl3buf.h +++ b/src/nanovg_gl3buf.h @@ -585,7 +585,8 @@ static void glnvg__xformToMat3x4(float* m3, float* t) m3[11] = 0.0f; } -static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms* frag, struct NVGpaint* paint, struct NVGscissor* scissor, float width) +static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms* frag, struct NVGpaint* paint, + struct NVGscissor* scissor, float width, float fringe) { struct GLNVGtexture* tex = NULL; float invxform[6]; @@ -607,11 +608,11 @@ static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms glnvg__xformToMat3x4(frag->scissorMat, invxform); frag->scissorExt[0] = scissor->extent[0]; frag->scissorExt[1] = scissor->extent[1]; - frag->scissorScale[0] = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]); - frag->scissorScale[1] = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]); + frag->scissorScale[0] = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]) / fringe; + frag->scissorScale[1] = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]) / fringe; } memcpy(frag->extent, paint->extent, sizeof(frag->extent)); - frag->strokeMult = width*0.5f + 0.5f; + frag->strokeMult = (width*0.5f + fringe*0.5f) / fringe; if (paint->image != 0) { tex = glnvg__findTexture(gl, paint->image); @@ -860,7 +861,7 @@ static void glnvg__vset(struct NVGvertex* vtx, float x, float y, float u, float vtx->v = v; } -static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, +static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, const float* bounds, const struct NVGpath* paths, int npaths) { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; @@ -918,15 +919,15 @@ static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscis frag = nvg__fragUniformPtr(gl, call->uniformOffset); frag->type = NSVG_SHADER_SIMPLE; // Fill shader - glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset + gl->fragSize), paint, scissor, 1.0001f); + glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset + gl->fragSize), paint, scissor, fringe, fringe); } else { call->uniformOffset = glnvg__allocFragUniforms(gl, 1); // Fill shader - glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, 1.0001f); + glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, fringe, fringe); } } -static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, +static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, float strokeWidth, const struct NVGpath* paths, int npaths) { struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr; @@ -956,7 +957,7 @@ static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGsc // Fill shader call->uniformOffset = glnvg__allocFragUniforms(gl, 1); - glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, strokeWidth); + glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, strokeWidth, fringe); } static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, @@ -977,7 +978,7 @@ static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NV // Fill shader call->uniformOffset = glnvg__allocFragUniforms(gl, 1); frag = nvg__fragUniformPtr(gl, call->uniformOffset); - glnvg__convertPaint(gl, frag, paint, scissor, 1.0f); + glnvg__convertPaint(gl, frag, paint, scissor, 1.0f, 1.0f); frag->type = NSVG_SHADER_IMG; }