From: Jean-Philippe Bruyère Date: Wed, 18 Apr 2018 23:26:52 +0000 (+0200) Subject: line caps X-Git-Tag: v0.1-alpha~145 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=f139ffba15bfb242010558cc8f1a5597fa331785;p=jp%2Fvkvg.git line caps --- diff --git a/README.md b/README.md index 3b4ccbd..bb7869d 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,5 @@ make # Run Make - Improve triangulation algorithm. - Offscreen pattern building. -- Matrix transformations. - SVG rendering. diff --git a/include/vkvg.h b/include/vkvg.h index 449bce8..b520c41 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -138,7 +138,7 @@ void vkvg_reset_clip (VkvgContext ctx); void vkvg_clip (VkvgContext ctx); void vkvg_clip_preserve (VkvgContext ctx); void vkvg_set_rgba (VkvgContext ctx, float r, float g, float b, float a); -void vkvg_set_linewidth (VkvgContext ctx, float width); +void vkvg_set_line_width (VkvgContext ctx, float width); void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap); void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join); void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y); diff --git a/src/vectors.c b/src/vectors.c index cdd877b..3bf377c 100644 --- a/src/vectors.c +++ b/src/vectors.c @@ -1,5 +1,9 @@ #include "vectors.h" +inline vec2 vec2_create (float x, float y) { + vec2 v = {x,y}; + return v; +} vec2 vec2_line_norm(vec2 a, vec2 b) { vec2 d = {b.x - a.x, b.y - a.y}; diff --git a/src/vectors.h b/src/vectors.h index d9ac190..18a50df 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -54,6 +54,7 @@ typedef struct { }vec2i16; float vec2_length (vec2 v); +vec2 vec2_create (float x, float y); vec2 vec2_norm (vec2 a); vec2 vec2_perp (vec2 a); vec2 vec2_add (vec2 a, vec2 b); diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 19dcf92..1047c3c 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -366,16 +366,38 @@ void vkvg_stroke_preserve (VkvgContext ctx) iL = lastPathPointIdx; }else{ lastPathPointIdx = ctx->pathes[ptrPath+1]; - vec2 bisec = vec2_line_norm(ctx->points[i], ctx->points[i+1]); - bisec = vec2_perp(bisec); - bisec = vec2_mult(bisec,hw); + vec2 n = vec2_line_norm(ctx->points[i], ctx->points[i+1]); + vec2 p0 = ctx->points[i]; + vec2 vhw = vec2_mult(n,hw); - v.pos = vec2_add(ctx->points[i], bisec); + if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) + p0 = vec2_sub(p0, vhw); + + vhw = vec2_perp(vhw); + + if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ + float step = M_PI_4 / hw; + float a = acos(n.x) + M_PI_2; + float a1 = a + M_PI; + + a+=step; + while (a < a1){ + _add_vertexf(ctx, cos(a) * hw + p0.x, sin(a) * hw + p0.y); + a+=step; + } + uint32_t p0Idx = ctx->vertCount; + for (int p = firstIdx; p < p0Idx; p++) + _add_triangle_indices(ctx, p+1, p, p0Idx+1); + firstIdx = p0Idx; + } + + v.pos = vec2_add(p0, vhw); _add_vertex(ctx, v); - v.pos = vec2_sub(ctx->points[i], bisec); + v.pos = vec2_sub(p0, vhw); _add_vertex(ctx, v); _add_tri_indices_for_rect(ctx, firstIdx); + iL = i++; } @@ -386,15 +408,36 @@ void vkvg_stroke_preserve (VkvgContext ctx) } if (!_path_is_closed(ctx,ptrPath)){ - vec2 bisec = vec2_line_norm(ctx->points[i-1], ctx->points[i]); - bisec = vec2_perp(bisec); - bisec = vec2_mult(bisec,hw); + vec2 n = vec2_line_norm(ctx->points[i-1], ctx->points[i]); + vec2 p0 = ctx->points[i]; + vec2 vhw = vec2_mult(n, hw); - v.pos = vec2_add(ctx->points[i], bisec); + if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) + p0 = vec2_add(p0, vhw); + + vhw = vec2_perp(vhw); + + v.pos = vec2_add(p0, vhw); _add_vertex(ctx, v); - v.pos = vec2_sub(ctx->points[i], bisec); + v.pos = vec2_sub(p0, vhw); _add_vertex(ctx, v); + if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ + firstIdx = ctx->vertCount; + float step = M_PI_4 / hw; + float a = acos(n.x) + M_PI_2; + float a1 = a - M_PI; + + a-=step; + while (a > a1){ + _add_vertexf(ctx, cos(a) * hw + p0.x, sin(a) * hw + p0.y); + a-=step; + } + uint32_t p0Idx = ctx->vertCount-1; + for (int p = firstIdx-1; p < p0Idx; p++) + _add_triangle_indices(ctx, p+1, p, firstIdx-2); + } + i++; }else{ iR = ctx->pathes[ptrPath]; @@ -528,7 +571,7 @@ void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ _init_cmd_buff (ctx); } -void vkvg_set_linewidth (VkvgContext ctx, float width){ +void vkvg_set_line_width (VkvgContext ctx, float width){ ctx->lineWidth = width; } void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap){ diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 23aa3a0..ca028d8 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -64,6 +64,14 @@ void _create_vertices_buff (VkvgContext ctx){ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, ctx->sizeIndices * sizeof(uint32_t), &ctx->indices); } +const vec3 blankuv = {}; +void _add_vertexf (VkvgContext ctx, float x, float y){ + Vertex* pVert = (Vertex*)(ctx->vertices.mapped + ctx->vertCount * sizeof(Vertex)); + pVert->pos.x = x; + pVert->pos.y = y; + pVert->uv = blankuv; + ctx->vertCount++; +} void _add_vertex(VkvgContext ctx, Vertex v){ Vertex* pVert = (Vertex*)(ctx->vertices.mapped + ctx->vertCount * sizeof(Vertex)); *pVert = v; @@ -294,7 +302,7 @@ void add_line(vkvg_context* ctx, vec2 p1, vec2 p2, vec4 col){ ctx->indCount+=2; } -void _build_vb_step (vkvg_context* ctx, Vertex v, double hw, uint32_t iL, uint32_t i, uint32_t iR){ +void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_t i, uint32_t iR){ double alpha = 0; vec2 v0n = vec2_line_norm(ctx->points[iL], ctx->points[i]); vec2 v1n = vec2_line_norm(ctx->points[i], ctx->points[iR]); @@ -303,7 +311,7 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, double hw, uint32_t iL, uint32 bisec = vec2_norm(bisec); alpha = acos(v0n.x*v1n.x+v0n.y*v1n.y)/2.0; - float lh = (float)hw / cos(alpha); + float lh = hw / cos(alpha); bisec = vec2_perp(bisec); bisec = vec2_mult(bisec,lh); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 8a71035..4663757 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -132,9 +132,11 @@ void _vkvg_fill_rectangle (VkvgContext ctx, float x, float y, float width, flo void _create_vertices_buff (VkvgContext ctx); void _add_vertex (VkvgContext ctx, Vertex v); +void _add_vertexf (VkvgContext ctx, float x, float y); void _set_vertex (VkvgContext ctx, uint32_t idx, Vertex v); void _add_triangle_indices (VkvgContext ctx, uint32_t i0, uint32_t i1,uint32_t i2); void _add_tri_indices_for_rect (VkvgContext ctx, uint32_t i); +void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_t i, uint32_t iR); void _create_cmd_buff (VkvgContext ctx); void _init_cmd_buff (VkvgContext ctx); diff --git a/tests/test1.c b/tests/test1.c index d5114d2..927f09a 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -392,7 +392,7 @@ void draw(VkEngine* e) { void vkvg_test_gradient (VkvgContext ctx) { VkvgPattern pat = vkvg_pattern_create_linear(100,0,300,0); - vkvg_set_linewidth(ctx, 20); + vkvg_set_line_width(ctx, 20); vkvg_patter_add_color_stop(pat, 0, 1, 0, 0, 1); vkvg_patter_add_color_stop(pat, 0.5, 0, 1, 0, 1); vkvg_patter_add_color_stop(pat, 1, 0, 0, 1, 1); @@ -430,7 +430,7 @@ void vkvg_test_fill(VkvgContext ctx){ void vkvg_test_curves (VkvgContext ctx) { vkvg_set_rgba (ctx, 0.5,0.0,1.0,0.5); - vkvg_set_linewidth(ctx, 10); + vkvg_set_line_width(ctx, 10); vkvg_move_to (ctx, 100, 400); @@ -445,7 +445,7 @@ void vkvg_test_curves (VkvgContext ctx) { } void vkvg_test_stroke(VkvgContext ctx){ - vkvg_set_linewidth(ctx, 2); + vkvg_set_line_width(ctx, 2); vkvg_set_rgba(ctx,1,0,0,1); vkvg_move_to(ctx,200.5,200.5); vkvg_line_to(ctx,400.5,200.5); @@ -463,7 +463,7 @@ void vkvg_test_stroke(VkvgContext ctx){ vkvg_line_to(ctx,300.5,500.5); vkvg_close_path(ctx); vkvg_stroke(ctx); - vkvg_set_linewidth(ctx, 40); + vkvg_set_line_width(ctx, 40); vkvg_restore(ctx); vkvg_set_rgba(ctx,0.5,0.6,1,1.0); vkvg_move_to(ctx,700,475); @@ -474,7 +474,7 @@ void vkvg_test_stroke(VkvgContext ctx){ vkvg_arc(ctx, 200,200,100,0, M_PI); vkvg_stroke(ctx); - vkvg_set_linewidth(ctx, 20); + vkvg_set_line_width(ctx, 20); vkvg_set_rgba(ctx,0.1,0.1,0.1,0.5); vkvg_move_to(ctx,100,60); vkvg_line_to(ctx,400,600); @@ -566,7 +566,7 @@ void test_text (VkvgContext ctx) { } void vkvg_test_stroke2(VkvgContext ctx){ - vkvg_set_linewidth(ctx,20); + vkvg_set_line_width(ctx,20); vkvg_set_rgba(ctx,1,0,0,1); vkvg_move_to(ctx,200,200); vkvg_line_to(ctx,400,200); @@ -581,7 +581,7 @@ void vkvg_test_stroke2(VkvgContext ctx){ vkvg_line_to(ctx,300,500); vkvg_close_path(ctx); vkvg_stroke(ctx); - vkvg_set_linewidth(ctx,10); + vkvg_set_line_width(ctx,10); vkvg_set_rgba(ctx,0.5,0.6,1,1); vkvg_move_to(ctx,700,475); vkvg_line_to(ctx,400,475); @@ -593,7 +593,7 @@ void vkvg_test_stroke2(VkvgContext ctx){ vkvg_stroke(ctx); - vkvg_set_linewidth(ctx,20); + vkvg_set_line_width(ctx,20); vkvg_set_rgba(ctx,1,1,0,1); vkvg_move_to(ctx,100,50); vkvg_line_to(ctx,400,50); @@ -633,6 +633,38 @@ void test_img_surface (VkvgContext ctx) { vkvg_surface_destroy(imgSurf); } +void test_line_caps (VkvgContext ctx) { + vkvg_set_line_cap(ctx,VKVG_LINE_CAP_ROUND); + + //vkvg_scale(ctx,4,4); + + vkvg_set_line_width(ctx,40); + vkvg_set_rgba(ctx,0,1,0,0.2); + vkvg_move_to(ctx,100,100); + vkvg_line_to(ctx,400,400); + vkvg_stroke(ctx); + vkvg_set_line_width(ctx,4); + vkvg_set_rgba(ctx,0,1,0,0.2); + vkvg_move_to(ctx,400,100); + vkvg_line_to(ctx,100,400); + vkvg_stroke(ctx); + + vkvg_set_line_cap(ctx,VKVG_LINE_CAP_BUTT); + + vkvg_set_line_width(ctx,20); + vkvg_set_rgba(ctx,1,0,0,1); + vkvg_move_to(ctx,100,100); + vkvg_line_to(ctx,400,400); + vkvg_stroke(ctx); + + vkvg_set_line_width(ctx,1); + vkvg_set_rgba(ctx,1,1,1,1); + vkvg_move_to(ctx,100,100); + vkvg_line_to(ctx,400,400); + vkvg_stroke(ctx); +} + + int main(int argc, char *argv[]) { dumpLayerExts(); @@ -655,6 +687,8 @@ int main(int argc, char *argv[]) { vkvg_set_rgba(ctx,0.0,0.0,0.1,1.0); vkvg_paint(ctx); + test_line_caps(ctx); + //vkvg_test_clip(ctx); vkvg_set_rgba (ctx,0.02,0.8,0.3,1.0);