|
|
@@ -1084,13 +1084,13 @@ static int nvg__curveDivs(float r, float arc, float tol) |
|
|
|
} |
|
|
|
|
|
|
|
static void nvg__chooseBevel(int bevel, struct NVGpoint* p0, struct NVGpoint* p1, float w, |
|
|
|
float* x0, float* y0, float* x1, float* y1, float fringe) |
|
|
|
float* x0, float* y0, float* x1, float* y1) |
|
|
|
{ |
|
|
|
if (bevel) { |
|
|
|
*x0 = p1->x + p0->dy * w + p0->dx * fringe; |
|
|
|
*y0 = p1->y - p0->dx * w + p0->dy * fringe; |
|
|
|
*x1 = p1->x + p1->dy * w - p1->dx * fringe; |
|
|
|
*y1 = p1->y - p1->dx * w - p1->dy * fringe; |
|
|
|
*x0 = p1->x + p0->dy * w; |
|
|
|
*y0 = p1->y - p0->dx * w; |
|
|
|
*x1 = p1->x + p1->dy * w; |
|
|
|
*y1 = p1->y - p1->dx * w; |
|
|
|
} else { |
|
|
|
*x0 = p1->x + p1->dmx * w; |
|
|
|
*y0 = p1->y + p1->dmy * w; |
|
|
@@ -1110,7 +1110,7 @@ static struct NVGvertex* nvg__roundJoin(struct NVGvertex* dst, struct NVGpoint* |
|
|
|
|
|
|
|
if (p1->flags & NVG_PT_LEFT) { |
|
|
|
float lx0,ly0,lx1,ly1,a0,a1; |
|
|
|
nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, lw, &lx0,&ly0, &lx1,&ly1, -fringe); |
|
|
|
nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, lw, &lx0,&ly0, &lx1,&ly1); |
|
|
|
a0 = atan2f(-dly0, -dlx0); |
|
|
|
a1 = atan2f(-dly1, -dlx1); |
|
|
|
if (a1 > a0) a1 -= NVG_PI*2; |
|
|
@@ -1133,7 +1133,7 @@ static struct NVGvertex* nvg__roundJoin(struct NVGvertex* dst, struct NVGpoint* |
|
|
|
|
|
|
|
} else { |
|
|
|
float rx0,ry0,rx1,ry1,a0,a1; |
|
|
|
nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1, -fringe); |
|
|
|
nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1); |
|
|
|
a0 = atan2f(dly0, dlx0); |
|
|
|
a1 = atan2f(dly1, dlx1); |
|
|
|
if (a1 < a0) a1 += NVG_PI*2; |
|
|
@@ -1161,48 +1161,85 @@ static struct NVGvertex* nvg__roundJoin(struct NVGvertex* dst, struct NVGpoint* |
|
|
|
static struct NVGvertex* nvg__bevelJoin(struct NVGvertex* dst, struct NVGpoint* p0, struct NVGpoint* p1, |
|
|
|
float lw, float rw, float lu, float ru, float fringe) |
|
|
|
{ |
|
|
|
int left = 0, right = 0; |
|
|
|
float dot, rf, lf; |
|
|
|
float rx0,ry0,rx1,ry1; |
|
|
|
float lx0,ly0,lx1,ly1; |
|
|
|
float mx,my,len,mu; |
|
|
|
int i, n; |
|
|
|
float dlx0 = p0->dy; |
|
|
|
float dly0 = -p0->dx; |
|
|
|
float dlx1 = p1->dy; |
|
|
|
float dly1 = -p1->dx; |
|
|
|
|
|
|
|
if (p1->flags & NVG_PT_LEFT) { |
|
|
|
left = p1->flags & NVG_PR_INNERBEVEL; |
|
|
|
right = p1->flags & NVG_PT_BEVEL; |
|
|
|
lf = 0; |
|
|
|
rf = fringe; |
|
|
|
} else { |
|
|
|
left = p1->flags & NVG_PT_BEVEL; |
|
|
|
right = p1->flags & NVG_PR_INNERBEVEL; |
|
|
|
lf = fringe; |
|
|
|
rf = 0; |
|
|
|
} |
|
|
|
nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, lw, &lx0,&ly0, &lx1,&ly1); |
|
|
|
|
|
|
|
nvg__chooseBevel(left, p0, p1, lw, &lx0,&ly0, &lx1,&ly1, lf); |
|
|
|
nvg__chooseBevel(right, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1, rf); |
|
|
|
nvg__vset(dst, lx0, ly0, lu,1); dst++; |
|
|
|
nvg__vset(dst, p1->x - dlx0*rw, p1->y - dly0*rw, ru,1); dst++; |
|
|
|
|
|
|
|
dot = p0->dx*p1->dx + p0->dy*p1->dy; |
|
|
|
dot = (1.0f - dot) * 0.5f; |
|
|
|
if (p1->flags & NVG_PT_BEVEL) { |
|
|
|
// TODO: this needs more work. |
|
|
|
mx = (dlx0 + dlx1) * 0.5f; |
|
|
|
my = (dly0 + dly1) * 0.5f; |
|
|
|
len = sqrtf(mx*mx + my*my); |
|
|
|
mu = ru + len*(lu-ru)*0.5f; |
|
|
|
|
|
|
|
nvg__vset(dst, lx0, ly0, lu,1); dst++; |
|
|
|
nvg__vset(dst, rx0, ry0, ru,1); dst++; |
|
|
|
nvg__vset(dst, lx0, ly0, lu,1); dst++; |
|
|
|
nvg__vset(dst, p1->x - dlx0*rw, p1->y - dly0*rw, ru,1); dst++; |
|
|
|
|
|
|
|
nvg__vset(dst, lx1, ly1, lu,1); dst++; |
|
|
|
nvg__vset(dst, p1->x - dlx1*rw, p1->y - dly1*rw, ru,1); dst++; |
|
|
|
} else { |
|
|
|
rx0 = p1->x - p1->dmx * rw; |
|
|
|
ry0 = p1->y - p1->dmy * rw; |
|
|
|
|
|
|
|
if (p1->flags & NVG_PR_INNERBEVEL) { |
|
|
|
if (p1->flags & NVG_PT_LEFT) { |
|
|
|
nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; |
|
|
|
nvg__vset(dst, p1->x - dlx0*rw, p1->y - dly0*rw, ru,1); dst++; |
|
|
|
|
|
|
|
nvg__vset(dst, rx0, ry0, ru,1); dst++; |
|
|
|
nvg__vset(dst, rx0, ry0, ru,1); dst++; |
|
|
|
|
|
|
|
nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; |
|
|
|
nvg__vset(dst, p1->x - dlx1*rw, p1->y - dly1*rw, ru,1); dst++; |
|
|
|
} |
|
|
|
|
|
|
|
nvg__vset(dst, lx1, ly1, lu,1); dst++; |
|
|
|
nvg__vset(dst, p1->x - dlx1*rw, p1->y - dly1*rw, ru,1); dst++; |
|
|
|
|
|
|
|
} else { |
|
|
|
nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1); |
|
|
|
|
|
|
|
nvg__vset(dst, p1->x + dlx0*lw, p1->y + dly0*lw, lu,1); dst++; |
|
|
|
nvg__vset(dst, rx0, ry0, ru,1); dst++; |
|
|
|
|
|
|
|
if (p1->flags & NVG_PT_BEVEL) { |
|
|
|
// TODO: this needs more work. |
|
|
|
mx = (dlx0 + dlx1) * 0.5f; |
|
|
|
my = (dly0 + dly1) * 0.5f; |
|
|
|
len = sqrtf(mx*mx + my*my); |
|
|
|
mu = lu + len*(ru-lu)*0.5f; |
|
|
|
|
|
|
|
nvg__vset(dst, p1->x + dlx0*lw, p1->y + dly0*lw, lu,1); dst++; |
|
|
|
nvg__vset(dst, rx0, ry0, ru,1); dst++; |
|
|
|
|
|
|
|
nvg__vset(dst, p1->x + dlx1*lw, p1->y + dly1*lw, lu,1); dst++; |
|
|
|
nvg__vset(dst, rx1, ry1, ru,1); dst++; |
|
|
|
} else { |
|
|
|
nvg__vset(dst, lx0, ly0, lu,1); dst++; |
|
|
|
lx0 = p1->x + p1->dmx * lw; |
|
|
|
ly0 = p1->y + p1->dmy * lw; |
|
|
|
|
|
|
|
nvg__vset(dst, p1->x + dlx0*lw, p1->y + dly0*lw, lu,1); dst++; |
|
|
|
nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; |
|
|
|
nvg__vset(dst, lx1, ly1, lu,1); dst++; |
|
|
|
|
|
|
|
nvg__vset(dst, lx0, ly0, lu,1); dst++; |
|
|
|
nvg__vset(dst, lx0, ly0, lu,1); dst++; |
|
|
|
|
|
|
|
nvg__vset(dst, p1->x + dlx1*lw, p1->y + dly1*lw, lu,1); dst++; |
|
|
|
nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
nvg__vset(dst, lx1, ly1, lu,1); dst++; |
|
|
|
nvg__vset(dst, rx1, ry1, ru,1); dst++; |
|
|
|
nvg__vset(dst, p1->x + dlx1*rw, p1->y + dly1*rw, lu,1); dst++; |
|
|
|
nvg__vset(dst, rx1, ry1, ru,1); dst++; |
|
|
|
} |
|
|
|
|
|
|
|
return dst; |
|
|
|
} |
|
|
@@ -1294,7 +1331,7 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w, |
|
|
|
if (lineCap == NVG_ROUND) |
|
|
|
cverts += (path->count + path->nbevel*(ncap+2) + 1) * 2; // plus one for loop |
|
|
|
else |
|
|
|
cverts += (path->count + path->nbevel*3 + 1) * 2; // plus one for loop |
|
|
|
cverts += (path->count + path->nbevel*5 + 1) * 2; // plus one for loop |
|
|
|
if (loop == 0) { |
|
|
|
// space for caps |
|
|
|
if (lineCap == NVG_ROUND) { |
|
|
|