]> O.S.I.I.S - jp/vkvg.git/commitdiff
line caps
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 18 Apr 2018 23:26:52 +0000 (01:26 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 18 Apr 2018 23:26:52 +0000 (01:26 +0200)
README.md
include/vkvg.h
src/vectors.c
src/vectors.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h
tests/test1.c

index 3b4ccbd9563b0f32cece781c9a079ea261ec76c9..bb7869db1ac8dbaff93376028215c2a1e1356908 100644 (file)
--- a/README.md
+++ b/README.md
@@ -61,6 +61,5 @@ make                                              # Run Make
 
 - Improve triangulation algorithm.
 - Offscreen pattern building.
-- Matrix transformations.
 - SVG rendering.
 
index 449bce8acdb28fa301ac67056cc79960bc694a60..b520c41aac1fcfba7daff893b6db9e0902ca9aaf 100644 (file)
@@ -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);
index cdd877b781b328b0bb57048a9978362c596fc5e2..3bf377c2c3e8b26ba314566a8a80093d4e0324bb 100644 (file)
@@ -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};
index d9ac190abbb773ca463b40ce520ed35fb0060806..18a50df5cb8440dc27e704a111935923dc6cb709 100644 (file)
@@ -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);
index 19dcf92b1b042ee5a328fd8a20809cfb22c6b869..1047c3cd117c39590b72e32630eea6a1cb8417db 100644 (file)
@@ -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){
index 23aa3a0542872bef49cf36a41af6951a9e10eed0..ca028d8adfd8e6f65800a9bd5244be008f6dd102 100644 (file)
@@ -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);
 
index 8a710352f816bc2111b0c865855a9b2b5f01e0fc..466375755967b71cb4600f505749f642a744174f 100644 (file)
@@ -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);
index d5114d2d49bf06010396de9b2c42b05f78962244..927f09af914258aaaed056b6c2403f31321e1f06 100644 (file)
@@ -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);