Browse Source

Do bevels only at control points

shared-context
Mikko Mononen 11 years ago
parent
commit
4a1e66a515
1 changed files with 17 additions and 11 deletions
  1. +17
    -11
      src/nanovg.c

+ 17
- 11
src/nanovg.c View File

@@ -46,6 +46,7 @@ enum NVGpointFlags
NVG_PT_BEVEL = 0x01, NVG_PT_BEVEL = 0x01,
NVG_PT_LEFT = 0x02, NVG_PT_LEFT = 0x02,
NVG_PT_CUSP = 0x04, NVG_PT_CUSP = 0x04,
NVG_PT_CORNER = 0x08,
}; };


enum NVGexpandFeatures { enum NVGexpandFeatures {
@@ -833,7 +834,7 @@ static struct NVGpoint* nvg__lastPoint(struct NVGcontext* ctx)
return NULL; return NULL;
} }


static void nvg__addPoint(struct NVGcontext* ctx, float x, float y)
static void nvg__addPoint(struct NVGcontext* ctx, float x, float y, int flags)
{ {
struct NVGpath* path = nvg__lastPath(ctx); struct NVGpath* path = nvg__lastPath(ctx);
struct NVGpoint* pt; struct NVGpoint* pt;
@@ -841,8 +842,10 @@ static void nvg__addPoint(struct NVGcontext* ctx, float x, float y)


if (ctx->cache->npoints > 0) { if (ctx->cache->npoints > 0) {
pt = nvg__lastPoint(ctx); pt = nvg__lastPoint(ctx);
if (nvg__ptEquals(pt->x,pt->y, x,y, ctx->distTol))
if (nvg__ptEquals(pt->x,pt->y, x,y, ctx->distTol)) {
pt->flags |= flags;
return; return;
}
} }


if (ctx->cache->npoints+1 > ctx->cache->cpoints) { if (ctx->cache->npoints+1 > ctx->cache->cpoints) {
@@ -855,6 +858,7 @@ static void nvg__addPoint(struct NVGcontext* ctx, float x, float y)
memset(pt, 0, sizeof(*pt)); memset(pt, 0, sizeof(*pt));
pt->x = x; pt->x = x;
pt->y = y; pt->y = y;
pt->flags = flags;


ctx->cache->npoints++; ctx->cache->npoints++;
path->count++; path->count++;
@@ -940,14 +944,14 @@ static void nvg__vset(struct NVGvertex* vtx, float x, float y, float u, float v)
static void nvg__tesselateBezier(struct NVGcontext* ctx, static void nvg__tesselateBezier(struct NVGcontext* ctx,
float x1, float y1, float x2, float y2, float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4, float x3, float y3, float x4, float y4,
int level)
int level, int type)
{ {
float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234;
if (level > 10) return; if (level > 10) return;


if (nvg__absf(x1+x3-x2-x2) + nvg__absf(y1+y3-y2-y2) + nvg__absf(x2+x4-x3-x3) + nvg__absf(y2+y4-y3-y3) < ctx->tessTol) { if (nvg__absf(x1+x3-x2-x2) + nvg__absf(y1+y3-y2-y2) + nvg__absf(x2+x4-x3-x3) + nvg__absf(y2+y4-y3-y3) < ctx->tessTol) {
nvg__addPoint(ctx, x4, y4);
nvg__addPoint(ctx, x4, y4, type);
return; return;
} }


@@ -964,8 +968,8 @@ static void nvg__tesselateBezier(struct NVGcontext* ctx,
x1234 = (x123+x234)*0.5f; x1234 = (x123+x234)*0.5f;
y1234 = (y123+y234)*0.5f; y1234 = (y123+y234)*0.5f;


nvg__tesselateBezier(ctx, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1);
nvg__tesselateBezier(ctx, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1);
nvg__tesselateBezier(ctx, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0);
nvg__tesselateBezier(ctx, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type);
} }


static void nvg__flattenPaths(struct NVGcontext* ctx, int lineCap, int lineJoin, float miterLimit) static void nvg__flattenPaths(struct NVGcontext* ctx, int lineCap, int lineJoin, float miterLimit)
@@ -994,12 +998,12 @@ static void nvg__flattenPaths(struct NVGcontext* ctx, int lineCap, int lineJoin,
case NVG_MOVETO: case NVG_MOVETO:
nvg__addPath(ctx); nvg__addPath(ctx);
p = &ctx->commands[i+1]; p = &ctx->commands[i+1];
nvg__addPoint(ctx, p[0], p[1]);
nvg__addPoint(ctx, p[0], p[1], NVG_PT_CORNER);
i += 3; i += 3;
break; break;
case NVG_LINETO: case NVG_LINETO:
p = &ctx->commands[i+1]; p = &ctx->commands[i+1];
nvg__addPoint(ctx, p[0], p[1]);
nvg__addPoint(ctx, p[0], p[1], NVG_PT_CORNER);
i += 3; i += 3;
break; break;
case NVG_BEZIERTO: case NVG_BEZIERTO:
@@ -1008,7 +1012,7 @@ static void nvg__flattenPaths(struct NVGcontext* ctx, int lineCap, int lineJoin,
cp1 = &ctx->commands[i+1]; cp1 = &ctx->commands[i+1];
cp2 = &ctx->commands[i+3]; cp2 = &ctx->commands[i+3];
p = &ctx->commands[i+5]; p = &ctx->commands[i+5];
nvg__tesselateBezier(ctx, last->x,last->y, cp1[0],cp1[1], cp2[0],cp2[1], p[0],p[1], 0);
nvg__tesselateBezier(ctx, last->x,last->y, cp1[0],cp1[1], cp2[0],cp2[1], p[0],p[1], 0, NVG_PT_CORNER);
} }
i += 7; i += 7;
break; break;
@@ -1107,8 +1111,10 @@ static void nvg__flattenPaths(struct NVGcontext* ctx, int lineCap, int lineJoin,
} }


// Check to see if the corner needs to be beveled. // Check to see if the corner needs to be beveled.
if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NVG_BEVEL || lineJoin == NVG_ROUND) {
p1->flags |= NVG_PT_BEVEL;
if (p1->flags & NVG_PT_CORNER) {
if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NVG_BEVEL || lineJoin == NVG_ROUND) {
p1->flags |= NVG_PT_BEVEL;
}
} }


if ((p1->flags & (NVG_PT_BEVEL | NVG_PT_CUSP)) != 0) if ((p1->flags & (NVG_PT_BEVEL | NVG_PT_CUSP)) != 0)


Loading…
Cancel
Save