]> O.S.I.I.S - jp/vkvg.git/commitdiff
debug curvesto, if last point of closed path is same pos as 1st, remove it
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 21 Apr 2018 00:50:35 +0000 (02:50 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 21 Apr 2018 00:50:35 +0000 (02:50 +0200)
include/vkvg.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h
tests/test1.c

index bee3457875c558dd0c6cf657d34a658227a51e83..cf2f9e9d19e9451eebb6f1b8e27703ed470d6f83 100644 (file)
@@ -161,8 +161,9 @@ void vkvg_paint             (VkvgContext ctx);
 void vkvg_reset_clip        (VkvgContext ctx);
 void vkvg_clip              (VkvgContext ctx);
 void vkvg_clip_preserve     (VkvgContext ctx);
-void vkvg_set_source_rgba                      (VkvgContext ctx, float r, float g, float b, float a);
-void vkvg_set_line_width               (VkvgContext ctx, float width);
+void vkvg_set_source_rgba      (VkvgContext ctx, float r, float g, float b, float a);
+void vkvg_set_source_rgb    (VkvgContext ctx, float r, float g, float b);
+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 45c055bd687c775dd853809ff23eacd0e3d0be78..2eac1eae1644f0566dd78470678cd614b06c103f 100644 (file)
@@ -163,6 +163,9 @@ void vkvg_close_path (VkvgContext ctx){
     if (ctx->pointCount - ctx->pathes [ctx->pathPtr-1] > 2){
         //set end idx of path to the same as start idx
         ctx->pathes[ctx->pathPtr] = ctx->pathes [ctx->pathPtr-1];
+        //if last point of path is same pos as first point, remove it
+        if (vec2_equ(ctx->points[ctx->pointCount-1], ctx->points[ctx->pathes[ctx->pathPtr]]))
+            ctx->pointCount--;
         //start new path
         _check_pathes_array(ctx);
         ctx->pathPtr++;
@@ -187,13 +190,6 @@ void vkvg_line_to (VkvgContext ctx, float x, float y)
         vkvg_move_to(ctx, x,y);
 }
 
-//this function expect that current path is empty (ctx->pathPtr % 2 == 0)
-void _start_sub_path (VkvgContext ctx){
-    //set start to current idx in point array
-    ctx->pathes[ctx->pathPtr] = ctx->pointCount;
-    _check_pathes_array(ctx);
-    ctx->pathPtr++;
-}
 void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2){
     while (a2 < a1)
         a2 += 2*M_PI;
@@ -281,7 +277,19 @@ void vkvg_move_to (VkvgContext ctx, float x, float y)
     ctx->curPosExists = true;
 }
 void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
-    _bezier (ctx, ctx->curPos.x, ctx->curPos.y, x1, y1, x2, y2, x3, y3);
+    vec2 p = ctx->curPos;
+    vec2 p1 = {x1,y1};
+
+    if (_current_path_is_empty(ctx)){
+        _start_sub_path(ctx);
+        if (!ctx->curPosExists)
+            p = p1;
+        if (!vec2_equ (p,p1))
+            _add_point (ctx, p.x, p.y);
+    }
+
+    _recursive_bezier       (ctx, p.x, p.y, x1, y1, x2, y2, x3, y3, 0);
+    _add_point_cp_update    (ctx, x3, y3);
 }
 void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
     vkvg_curve_to (ctx, ctx->curPos.x + x1, ctx->curPos.y + y1, ctx->curPos.x + x2, ctx->curPos.y + y2, ctx->curPos.x + x3, ctx->curPos.y + y3);
@@ -315,14 +323,6 @@ void vkvg_clip_preserve (VkvgContext ctx){
     vkCmdSetStencilReference(ctx->cmd,VK_STENCIL_FRONT_AND_BACK, ctx->stencilRef);
 }
 void vkvg_reset_clip (VkvgContext ctx){
-    /*
-    VkClearValue  clearValue = {0};
-    VkClearAttachment clrAtt = {VK_IMAGE_ASPECT_STENCIL_BIT, 2 ,clearValue};
-    VkClearRect clr = {{{0,0},{ctx->pSurf->width,ctx->pSurf->height}},0,1};
-    ctx->stencilRef=0;
-    vkCmdSetStencilReference(ctx->cmd,VK_STENCIL_FRONT_AND_BACK, ctx->stencilRef);
-    vkCmdClearAttachments (ctx->cmd ,1,&clrAtt,1,&clr);
-    */
     _flush_cmd_buff(ctx);
     _clear_stencil(ctx->pSurf);
     ctx->stencilRef=0;
@@ -555,6 +555,9 @@ void vkvg_paint (VkvgContext ctx){
     _record_draw_cmd (ctx);
 }
 
+inline void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b) {
+    vkvg_set_source_rgba (ctx, r, g, b, 1);
+}
 void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a)
 {
     uint32_t lastPat = ctx->pushConsts.patternType;
index dee4686bc1f634469d17a4ee0902d014bd97e778..e8131aec521262fbf7314ac78f1effdd56f25625 100644 (file)
@@ -44,6 +44,13 @@ void _check_pathes_array (VkvgContext ctx){
 inline bool _current_path_is_empty (VkvgContext ctx) {
     return ctx->pathPtr % 2 == 0;
 }
+//this function expect that current path is empty
+void _start_sub_path (VkvgContext ctx) {
+    //set start to current idx in point array
+    ctx->pathes[ctx->pathPtr] = ctx->pointCount;
+    _check_pathes_array(ctx);
+    ctx->pathPtr++;
+}
 void _add_point (VkvgContext ctx, float x, float y){
     vec2 v = {x,y};
     ctx->points[ctx->pointCount] = v;
@@ -622,19 +629,3 @@ void _recursive_bezier (VkvgContext ctx,
     _recursive_bezier(ctx, x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1);
 }
 
-//------------------------------------------------------------------------
-void _bezier (VkvgContext ctx,
-              float x1, float y1,
-              float x2, float y2,
-              float x3, float y3,
-              float x4, float y4) {
-    if (ctx->pathPtr % 2 == 0){//current path is empty
-        //set start to current idx in point array
-        ctx->pathes[ctx->pathPtr] = ctx->pointCount;
-        _check_pathes_array(ctx);
-        ctx->pathPtr++;
-    }
-    _add_point              (ctx, x1, y1);
-    _recursive_bezier       (ctx, x1, y1, x2, y2, x3, y3, x4, y4, 0);
-    _add_point_cp_update    (ctx, x4, y4);
-}
index ff85ea435cc16ac2dec472ba26c45f2a828bc0fd..ec38078ab1bc2051277473e748a41b6bf71ce072 100644 (file)
@@ -145,6 +145,7 @@ typedef struct _vkvg_context_t {
 }vkvg_context;
 
 bool _current_path_is_empty (VkvgContext ctx);
+void _start_sub_path        (VkvgContext ctx);
 void _check_pathes_array       (VkvgContext ctx);
 float _normalizeAngle       (float a);
 
index f9c11571905a337e5b72c41c584907b8eef4cd6a..2459f7b0dcc96e5b03f3b61e7ae7221a5545ba3c 100644 (file)
@@ -450,7 +450,7 @@ void vkvg_test_fill(VkvgContext ctx){
     vkvg_fill(ctx);
 }
 
-void vkvg_test_curves (VkvgContext ctx) {
+void vkvg_test_curves2 (VkvgContext ctx) {
     vkvg_set_source_rgba   (ctx, 0.5,0.0,1.0,0.5);
     vkvg_set_line_width(ctx, 10);
 
@@ -465,7 +465,32 @@ void vkvg_test_curves (VkvgContext ctx) {
 
     vkvg_stroke     (ctx);
 }
+void vkvg_test_curves (VkvgContext ctx){
 
+    vkvg_set_line_width(ctx, 10);
+    vkvg_set_source_rgb   (ctx, 0,0,0);
+
+    vkvg_arc(ctx, 150, 100, 10, 0, M_PI*2);
+    vkvg_fill(ctx);
+    vkvg_arc(ctx, 200, 200, 10, 0, M_PI*2);
+    vkvg_fill(ctx);
+
+    vkvg_set_source_rgba   (ctx, 0.5,0.0,1.0,0.5);
+    vkvg_move_to(ctx,100,100);
+    vkvg_line_to(ctx,200,100);
+    vkvg_curve_to(ctx,250,100,300,150,300,200);
+    vkvg_line_to(ctx,300,300);
+    vkvg_curve_to(ctx,300,350,250,400,200,400);
+    vkvg_line_to(ctx,100,400);
+    vkvg_curve_to(ctx,50,400,10,350,10,300);
+    vkvg_line_to(ctx,10,200);
+    vkvg_curve_to(ctx,10,150,50,100,100,100);
+    vkvg_close_path(ctx);
+    //vkvg_curve_to(ctx, 150,100,200,150,200,200);
+    vkvg_fill_preserve(ctx);
+    vkvg_set_source_rgba   (ctx, 1,1,1.0,0.5);
+    vkvg_stroke(ctx);
+}
 void vkvg_test_stroke(VkvgContext ctx){
     vkvg_set_line_width(ctx, 2);
     vkvg_set_source_rgba(ctx,1,0,0,1);
@@ -502,7 +527,6 @@ void vkvg_test_stroke(VkvgContext ctx){
     vkvg_line_to(ctx,400,600);
     vkvg_stroke(ctx);
 }
-
 void test_text (VkvgContext ctx) {
     int size = 19;
     int penY = 50;
@@ -586,7 +610,6 @@ void test_text (VkvgContext ctx) {
     //vkvg_show_text (ctx,"ABCDABCD");
     //vkvg_show_text (ctx,"j");
 }
-
 void vkvg_test_stroke2(VkvgContext ctx){
     vkvg_set_line_width(ctx,20);
     vkvg_set_source_rgba(ctx,1,0,0,1);
@@ -635,7 +658,6 @@ void vkvg_test_fill2(VkvgContext ctx){
     vkvg_close_path(ctx);
     vkvg_fill(ctx);
 }
-
 void test_img_surface (VkvgContext ctx) {
     VkvgSurface imgSurf;// = vkvg_surface_create_from_image(device, "/mnt/data/images/blason.png");
     //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/2000px-Tux.svg.png");
@@ -654,7 +676,6 @@ void test_img_surface (VkvgContext ctx) {
     vkvg_flush(ctx);
     vkvg_surface_destroy(imgSurf);
 }
-
 void test_line_caps (VkvgContext ctx) {
 
     float x = 20, y = 20, dx = 30, dy = 60;
@@ -700,7 +721,6 @@ void test_line_caps (VkvgContext ctx) {
     vkvg_rel_line_to(ctx,0,dy);
     vkvg_stroke(ctx);
 }
-
 void test_line_join (VkvgContext ctx){
     float x = 50, y = 150, dx = 150, dy = 140;
 
@@ -750,6 +770,21 @@ void test_line_join (VkvgContext ctx){
     vkvg_stroke(ctx);
     vkvg_set_line_join(ctx,VKVG_LINE_JOIN_MITER);
 }
+void test_colinear () {
+    VkvgContext ctx = vkvg_create(surf);
+    vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1);
+    vkvg_paint(ctx);
+
+    vkvg_set_source_rgba(ctx,0,0,0,1);
+    vkvg_set_line_width(ctx,10);
+
+    vkvg_move_to(ctx,100,100);
+    vkvg_line_to(ctx,100,200);
+    vkvg_line_to(ctx,100,100);
+    vkvg_stroke(ctx);
+
+    vkvg_destroy(ctx);
+}
 
 void multi_test1 () {
     VkvgSurface surf2 = vkvg_surface_create (device,1024,800);;
@@ -760,7 +795,7 @@ void multi_test1 () {
 //    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND);
 
 
-    //test_line_join(ctx);
+    test_line_join(ctx);
 
     //vkvg_test_clip(ctx);
 
@@ -773,14 +808,14 @@ void multi_test1 () {
 
     test_text(ctx);
     vkvg_test_fill2(ctx);
-    //vkvg_test_fill(ctx);
+    vkvg_test_fill(ctx);
 
 //    vkvg_translate(ctx, 10,10);
 //    vkvg_rotate(ctx, 0.2);
     //vkvg_scale(ctx, 2,2);
 
-    //vkvg_test_stroke(ctx);
-//    vkvg_test_gradient (ctx);
+    vkvg_test_stroke(ctx);
+    vkvg_test_gradient (ctx);
     vkvg_test_curves(ctx);
 
     //test_img_surface(ctx);
@@ -798,6 +833,81 @@ void multi_test1 () {
     vkvg_surface_destroy(surf2);
 }
 
+void cairo_test_clip (VkvgContext cr){
+    vkvg_arc (cr, 128.0, 128.0, 76.8, 0, 2 * M_PI);
+    vkvg_clip (cr);
+
+    //vkvg_new_path (cr);  /* current path is not
+    //                         consumed by vkvg_clip() */
+    vkvg_set_source_rgba(cr, 0, 0, 0, 1);
+    vkvg_rectangle (cr, 0, 0, 256, 256);
+    vkvg_fill (cr);
+    vkvg_set_source_rgba (cr, 0, 1, 0, 1);
+    vkvg_move_to (cr, 0, 0);
+    vkvg_line_to (cr, 256, 256);
+    vkvg_move_to (cr, 256, 0);
+    vkvg_line_to (cr, 0, 256);
+    vkvg_set_line_width (cr, 10.0);
+    vkvg_stroke (cr);
+}
+
+void cairo_test_rounded_rect (VkvgContext cr) {
+    /* a custom shape that could be wrapped in a function */
+    float x0      = 25.6,   /* parameters like vkvg_rectangle */
+           y0      = 25.6,
+           rect_width  = 204.8,
+           rect_height = 204.8,
+           radius = 102.4;   /* and an approximate curvature radius */
+
+    float x1,y1;
+
+    x1=x0+rect_width;
+    y1=y0+rect_height;
+    if (!rect_width || !rect_height)
+        return;
+    if (rect_width/2<radius) {
+        if (rect_height/2<radius) {
+            vkvg_move_to  (cr, x0, (y0 + y1)/2);
+            vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
+            vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
+            vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
+            vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
+        } else {
+            vkvg_move_to  (cr, x0, y0 + radius);
+            vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
+            vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+            vkvg_line_to (cr, x1 , y1 - radius);
+            vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
+            vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
+        }
+    } else {
+        if (rect_height/2<radius) {
+            vkvg_move_to  (cr, x0, (y0 + y1)/2);
+            vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
+            vkvg_line_to (cr, x1 - radius, y0);
+            vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
+            vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+            vkvg_line_to (cr, x0 + radius, y1);
+            vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
+        } else {
+            vkvg_move_to  (cr, x0, y0 + radius);
+            vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
+            vkvg_line_to (cr, x1 - radius, y0);
+            vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+            vkvg_line_to (cr, x1 , y1 - radius);
+            vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+            vkvg_line_to (cr, x0 + radius, y1);
+            vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
+        }
+    }
+    vkvg_close_path (cr);
+
+    vkvg_set_source_rgb (cr, 0.5, 0.5, 1);
+    vkvg_fill_preserve (cr);
+    vkvg_set_source_rgba (cr, 0.5, 0, 0, 0.5);
+    vkvg_set_line_width (cr, 10.0);
+    vkvg_stroke (cr);
+}
 void cairo_print_arc_neg (VkvgContext cr){
     float xc = 128.0;
     float yc = 128.0;
@@ -853,9 +963,11 @@ void cairo_tests () {
     VkvgContext ctx = vkvg_create(surf);
     vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1);
     vkvg_paint(ctx);
-    cairo_print_arc(ctx);
-    vkvg_translate(ctx,200,0);
-    cairo_print_arc_neg(ctx);
+    //cairo_print_arc(ctx);
+    //cairo_print_arc_neg(ctx);
+    //cairo_test_clip(ctx);
+    cairo_test_rounded_rect(ctx);
+    //vkvg_test_curves(ctx);
     vkvg_destroy(ctx);
 }
 
@@ -900,8 +1012,11 @@ int main(int argc, char *argv[]) {
     //multi_test1();
 
     //test_grad_transforms();
+
     cairo_tests();
 
+    //test_colinear();
+
     setupSimpleBlit(&e.renderer);
 
     while (!glfwWindowShouldClose(e.renderer.window)) {