From 6edc46e5b0bd501e2aa60460b35b7eb88c776fb8 Mon Sep 17 00:00:00 2001 From: Mikko Mononen Date: Sat, 19 Apr 2014 20:03:46 +0300 Subject: [PATCH] Allow small strokes, fixed textBoxBounds() - added test for multiple stroke widths - allow stroke width down to 1px size, then scale with alpha - fixed textBoxBounds() in hi-dpi --- example/demo.c | 24 ++++++++++++++++++++++++ src/nanovg.c | 22 ++++++++++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/example/demo.c b/example/demo.c index 8ceaf50..2859574 100644 --- a/example/demo.c +++ b/example/demo.c @@ -915,6 +915,27 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h nvgRestore(vg); } +void drawWidths(struct NVGcontext* vg, float x, float y, float width) +{ + int i; + + nvgSave(vg); + + nvgStrokeColor(vg, nvgRGBA(0,0,0,255)); + + for (i = 0; i < 20; i++) { + float w = (i+0.5f)*0.1f; + nvgStrokeWidth(vg, w); + nvgBeginPath(vg); + nvgMoveTo(vg, x,y); + nvgLineTo(vg, x+width,y+width*0.3f); + nvgStroke(vg); + y += 10; + } + + nvgRestore(vg); +} + void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float height, float t, int blowup, struct DemoData* data) { @@ -928,6 +949,9 @@ void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float he // Line joints drawLines(vg, 50, height-50, 600, 50, t); + // Line width; + drawWidths(vg, 10, 50, 30); + nvgSave(vg); if (blowup) { nvgRotate(vg, sinf(t*0.3f)*5.0f/180.0f*NVG_PI); diff --git a/src/nanovg.c b/src/nanovg.c index 631fb4a..b8d5600 100644 --- a/src/nanovg.c +++ b/src/nanovg.c @@ -1840,17 +1840,27 @@ void nvgStroke(struct NVGcontext* ctx) { struct NVGstate* state = nvg__getState(ctx); float scale = nvg__getAverageScale(state->xform); - float strokeWidth = nvg__clampf(state->strokeWidth * scale, 1.0f, 20.0f); + float strokeWidth = nvg__clampf(state->strokeWidth * scale, 0.0f, 20.0f); + struct NVGpaint strokePaint = state->stroke; const struct NVGpath* path; int i; + if (strokeWidth < ctx->fringeWidth) { + // If the stroke width is less than pixel size, use alpha to emulate coverate. + // Since coverage is area, scale by alpha*alpha. + float alpha = nvg__clampf(strokeWidth / ctx->fringeWidth, 0.0f, 1.0f); + strokePaint.innerColor.a *= alpha*alpha; + strokePaint.outerColor.a *= alpha*alpha; + strokeWidth = ctx->fringeWidth; + } + nvg__flattenPaths(ctx); if (ctx->params.edgeAntiAlias) 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->fringeWidth, + ctx->params.renderStroke(ctx->params.userPtr, &strokePaint, &state->scissor, ctx->fringeWidth, strokeWidth, ctx->cache->paths, ctx->cache->npaths); // Count triangles @@ -2359,10 +2369,10 @@ void nvgTextBoxBounds(struct NVGcontext* ctx, float x, float y, float breakRowWi state->textAlign = oldAlign; if (bounds != NULL) { - bounds[0] = minx * invscale; - bounds[1] = miny * invscale; - bounds[2] = maxx * invscale; - bounds[3] = maxy * invscale; + bounds[0] = minx; + bounds[1] = miny; + bounds[2] = maxx; + bounds[3] = maxy; } }