]> O.S.I.I.S - jp/vkvg.git/commitdiff
line join basis, try to cover every angles for line but, missing triangle when normal...
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 19 Apr 2018 18:19:48 +0000 (20:19 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 19 Apr 2018 18:19:48 +0000 (20:19 +0200)
include/vkvg.h
src/vectors.c
src/vectors.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_matrix.c
tests/test1.c

index b520c41aac1fcfba7daff893b6db9e0902ca9aaf..735a1abdd01468ea8047a28f04d1cc5c75c6f63b 100644 (file)
@@ -125,7 +125,9 @@ void vkvg_flush                             (VkvgContext ctx);
 
 void vkvg_close_path           (VkvgContext ctx);
 void vkvg_line_to                      (VkvgContext ctx, float x, float y);
+void vkvg_rel_line_to       (VkvgContext ctx, float x, float y);
 void vkvg_move_to                      (VkvgContext ctx, float x, float y);
+void vkvg_rel_move_to          (VkvgContext ctx, float x, float y);
 void vkvg_arc                          (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2);
 void vkvg_curve_to          (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3);
 void vkvg_rectangle         (VkvgContext ctx, float x, float y, float w, float h);
index 3bf377c2c3e8b26ba314566a8a80093d4e0324bb..fdef0afae029c77550210e40f15a1f050f352f1e 100644 (file)
@@ -80,3 +80,7 @@ bool vec2_equ (vec2 a, vec2 b){
         return true;
     return false;
 }
+void vec2_inv (vec2* v){
+    v->x = -v->x;
+    v->y = -v->y;
+}
index 18a50df5cb8440dc27e704a111935923dc6cb709..05657f8021972763b9b666e427d06459849adbeb 100644 (file)
@@ -72,4 +72,5 @@ vec2d         vec2d_mult      (vec2d a, double m);
 vec2d          vec2d_line_norm(vec2d a, vec2d b);
 
 vec2           vec2d_to_vec2(vec2d vd);
+void        vec2_inv    (vec2* v);
 #endif
index 1047c3cd117c39590b72e32630eea6a1cb8417db..c063a5088c83be893420ab8a8a8342a83b902236 100644 (file)
@@ -146,7 +146,9 @@ void vkvg_close_path (VkvgContext ctx){
         ctx->pathPtr++;
     }
 }
-
+void vkvg_rel_line_to (VkvgContext ctx, float x, float y){
+    vkvg_line_to(ctx, ctx->curPos.x + x, ctx->curPos.y + y);
+}
 void vkvg_line_to (VkvgContext ctx, float x, float y)
 {
     if (ctx->pathPtr % 2 == 0){//current path is empty
@@ -202,7 +204,10 @@ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, floa
     if (!vec2_equ (v,ctx->curPos))
         _add_point_cp_update(ctx,v.x,v.y);
 }
-
+void vkvg_rel_move_to (VkvgContext ctx, float x, float y)
+{
+    vkvg_move_to(ctx, ctx->curPos.x + x, ctx->curPos.y + y);
+}
 void vkvg_move_to (VkvgContext ctx, float x, float y)
 {
     _finish_path(ctx);
@@ -213,6 +218,10 @@ void vkvg_move_to (VkvgContext ctx, float x, float y)
 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);
 }
+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);
+}
+
 void vkvg_rectangle (VkvgContext ctx, float x, float y, float w, float h){
     _finish_path (ctx);
 
@@ -356,8 +365,6 @@ void vkvg_stroke_preserve (VkvgContext ctx)
 
     uint32_t lastPathPointIdx, iL, iR;
 
-
-
     while (ptrPath < ctx->pathPtr){
         uint32_t firstIdx = ctx->vertCount;
 
@@ -367,6 +374,7 @@ void vkvg_stroke_preserve (VkvgContext ctx)
         }else{
             lastPathPointIdx = ctx->pathes[ptrPath+1];
             vec2 n = vec2_line_norm(ctx->points[i], ctx->points[i+1]);
+
             vec2 p0 = ctx->points[i];
             vec2 vhw = vec2_mult(n,hw);
 
@@ -376,8 +384,16 @@ void vkvg_stroke_preserve (VkvgContext ctx)
             vhw = vec2_perp(vhw);
 
             if (ctx->lineCap == VKVG_LINE_CAP_ROUND){
-                float step = M_PI_4 / hw;
+                float step = M_PI_2 / hw;
                 float a = acos(n.x) + M_PI_2;
+                if (n.y < 0){
+                    a = asin(n.y);
+                    if (n.x < 0)
+                        a += M_PI/8;
+                    else
+                        a += M_PI_2;
+                }
+
                 float a1 = a + M_PI;
 
                 a+=step;
@@ -387,7 +403,7 @@ void vkvg_stroke_preserve (VkvgContext ctx)
                 }
                 uint32_t p0Idx = ctx->vertCount;
                 for (int p = firstIdx; p < p0Idx; p++)
-                    _add_triangle_indices(ctx, p+1, p, p0Idx+1);
+                    _add_triangle_indices(ctx, p0Idx+1, p, p+1);
                 firstIdx = p0Idx;
             }
 
@@ -397,7 +413,6 @@ void vkvg_stroke_preserve (VkvgContext ctx)
             _add_vertex(ctx, v);
             _add_tri_indices_for_rect(ctx, firstIdx);
 
-
             iL = i++;
         }
 
@@ -424,17 +439,27 @@ void vkvg_stroke_preserve (VkvgContext ctx)
 
             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 step = M_PI_2 / hw;
+                float a = acos(n.x)+ M_PI_2;
+                if (n.y < 0){
+                    a = asin(n.y);
+                    if (n.x < 0)
+                        a += M_PI/8;
+                    else
+                        a += M_PI_2;
+                }
                 float a1 = a - M_PI;
-
                 a-=step;
-                while (a > a1){
+                while ( a > a1){
                     _add_vertexf(ctx, cos(a) * hw + p0.x, sin(a) * hw + p0.y);
                     a-=step;
                 }
+
+                //printf("x = %f; y = %f ; acos(n.x)=%f ;  ", n.x, n.y, acos(n.x));
+                //printf("sin(acos(n.x))=%f ;  \n", (acos(n.x)));
+
                 uint32_t p0Idx = ctx->vertCount-1;
-                for (int p = firstIdx-1; p < p0Idx; p++)
+                for (int p = firstIdx-1 ; p < p0Idx; p++)
                     _add_triangle_indices(ctx, p+1, p, firstIdx-2);
             }
 
index ca028d8adfd8e6f65800a9bd5244be008f6dd102..49a7aca104b633a05321c98ae557b1e27cb71f94 100644 (file)
@@ -308,6 +308,7 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_
     vec2 v1n = vec2_line_norm(ctx->points[i], ctx->points[iR]);
 
     vec2 bisec = vec2_add(v0n,v1n);
+
     bisec = vec2_norm(bisec);
     alpha = acos(v0n.x*v1n.x+v0n.y*v1n.y)/2.0;
 
@@ -315,6 +316,50 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_
     bisec = vec2_perp(bisec);
     bisec = vec2_mult(bisec,lh);
 
+    uint32_t idx = ctx->vertCount;
+
+    if (ctx->lineJoint == VKVG_LINE_JOIN_MITER){
+        v.pos = vec2_add(ctx->points[i], bisec);
+        _add_vertex(ctx, v);
+        v.pos = vec2_sub(ctx->points[i], bisec);
+        _add_vertex(ctx, v);
+        _add_tri_indices_for_rect(ctx, idx);
+    }else{
+        vec2 vp = vec2_perp(v0n);
+        v.pos = vec2_add (ctx->points[i], vec2_mult (vp, hw));
+        _add_vertex(ctx, v);
+        v.pos = vec2_sub (ctx->points[i], bisec);
+        _add_vertex(ctx, v);
+
+        if (ctx->lineJoint == VKVG_LINE_JOIN_BEVEL){
+            _add_triangle_indices(ctx, idx, idx+2, idx+1);
+            _add_triangle_indices(ctx, idx+2, idx+3, idx+1);
+            _add_triangle_indices(ctx, idx+1, idx+3, idx+4);
+        }else if (ctx->lineJoint == VKVG_LINE_JOIN_ROUND){
+            float step = M_PI / hw;
+            float a = acos(-vp.x) + M_PI;
+            float a1 = a + alpha*2;//acos(v0n.x) + M_PI;
+
+            a+=step;
+            while (a < a1){
+                _add_vertexf(ctx, cos(a) * hw + ctx->points[i].x, sin(a) * hw + ctx->points[i].y);
+                a+=step;
+            }
+            uint32_t p0Idx = ctx->vertCount;
+            _add_triangle_indices(ctx, idx, idx+2, idx+1);
+            for (int p = idx+2; p < p0Idx; p++)
+                _add_triangle_indices(ctx, p, p+1, idx+1);
+
+            _add_triangle_indices(ctx, p0Idx, p0Idx+1, idx+1);
+            _add_triangle_indices(ctx, idx+1, p0Idx+1, p0Idx+2);
+        }
+        vp = vec2_mult (vec2_perp(v1n), hw);
+        v.pos = vec2_add (ctx->points[i], vp);
+        _add_vertex(ctx, v);
+
+    }
+
+/*
 #ifdef DEBUG
 
     debugLinePoints[dlpCount] = ctx->points[i];
@@ -326,13 +371,7 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_
     debugLinePoints[dlpCount] = ctx->points[i];
     debugLinePoints[dlpCount+1] = ctx->points[iR];
     dlpCount+=2;
-#endif
-    uint32_t firstIdx = ctx->vertCount;
-    v.pos = vec2_add(ctx->points[i], bisec);
-    _add_vertex(ctx, v);
-    v.pos = vec2_sub(ctx->points[i], bisec);
-    _add_vertex(ctx, v);
-    _add_tri_indices_for_rect(ctx, firstIdx);
+#endif*/
 }
 
 bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) {
index bcfeb111df34d1dffbcbe01ef960e63842b087d8..e0084a0d7ae34f690af0c29f0a6e2a0b46ee59d6 100644 (file)
@@ -1,3 +1,41 @@
+//most of the matrix logic is grabbed from cairo, so here is the
+//licence:
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2002 University of Southern California
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *     Carl D. Worth <cworth@cworth.org>
+ */
+
 #include "vkvg_matrix.h"
 
 #define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
index 927f09af914258aaaed056b6c2403f31321e1f06..39fc6cad61204d6313cd5731cc08f0996e6cd5b6 100644 (file)
@@ -634,37 +634,75 @@ void test_img_surface (VkvgContext ctx) {
 }
 
 void test_line_caps (VkvgContext ctx) {
-    vkvg_set_line_cap(ctx,VKVG_LINE_CAP_ROUND);
 
+    float x = 50, y = 20, dx = 40, dy = 60;
     //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_set_line_width(ctx,36);
+    vkvg_set_rgba(ctx,0,0,0,1);
+    vkvg_move_to(ctx,x,y);
+    vkvg_rel_line_to(ctx,0,dy);
     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_set_line_cap(ctx,VKVG_LINE_CAP_SQUARE);
+    vkvg_rel_move_to(ctx,dx,-dy);
+    vkvg_rel_line_to(ctx,0,dy);
+    vkvg_stroke(ctx);
+    vkvg_set_line_cap(ctx,VKVG_LINE_CAP_ROUND);
+    vkvg_rel_move_to(ctx,dx,-dy);
+    vkvg_rel_line_to(ctx,0,dy);
+    vkvg_rel_move_to(ctx,dx,-dy);
+    vkvg_rel_line_to(ctx,dx,dy);
+    vkvg_rel_move_to(ctx,dx,-dy/2);
+    vkvg_rel_line_to(ctx,dx,0);
+    vkvg_rel_move_to(ctx,dx,dy/2);
+    vkvg_rel_line_to(ctx,dx,-dy);
+    vkvg_rel_move_to(ctx,dx,dy);
+    vkvg_rel_line_to(ctx,0,-dy);
+    vkvg_rel_move_to(ctx,2*dx,dy);
+    vkvg_rel_line_to(ctx,-dx,-dy);
+    vkvg_rel_move_to(ctx,3*dx,dy/2);
+    vkvg_rel_line_to(ctx,-dx,0);
+    /*vkvg_rel_line_to(ctx,0,-dy);
+    vkvg_rel_move_to(ctx,dx,dy/2);
+    vkvg_rel_line_to(ctx,dx,0);*/
     vkvg_stroke(ctx);
 
     vkvg_set_line_cap(ctx,VKVG_LINE_CAP_BUTT);
-
-    vkvg_set_line_width(ctx,20);
+    vkvg_set_line_width(ctx,1);
     vkvg_set_rgba(ctx,1,0,0,1);
-    vkvg_move_to(ctx,100,100);
-    vkvg_line_to(ctx,400,400);
+    vkvg_move_to(ctx,x,y);
+    vkvg_rel_line_to(ctx,0,dy);
+    vkvg_rel_move_to(ctx,dx,-dy);
+    vkvg_rel_line_to(ctx,0,dy);
+    vkvg_rel_move_to(ctx,dx,-dy);
+    vkvg_rel_line_to(ctx,0,dy);
     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);
+void test_line_join (VkvgContext ctx){
+    float x = 50, y = 200, dx = 100, dy = 30;
+
+    //vkvg_scale(ctx,4,4);
+
+    vkvg_set_line_width(ctx,30);
+    vkvg_set_rgba(ctx,0,0,0,1);
+    vkvg_move_to(ctx,x,y);
+    vkvg_rel_line_to(ctx,50,-40);
+    vkvg_rel_line_to(ctx,50,40);
+    vkvg_stroke(ctx);
+    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
+    vkvg_rel_move_to(ctx,-100,60);
+    vkvg_rel_line_to(ctx,50,-40);
+    vkvg_rel_line_to(ctx,50,40);
     vkvg_stroke(ctx);
+    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND);
+    vkvg_rel_move_to(ctx,-100,60);
+    vkvg_rel_line_to(ctx,50,-50);
+    vkvg_rel_line_to(ctx,50,50);
+    vkvg_stroke(ctx);
+    vkvg_set_line_join(ctx,VKVG_LINE_JOIN_MITER);
 }
 
-
 int main(int argc, char *argv[]) {
     dumpLayerExts();
 
@@ -684,19 +722,19 @@ int main(int argc, char *argv[]) {
     VkvgSurface surf2 = vkvg_surface_create (device,1024,800);;
     VkvgContext ctx = vkvg_create(surf2);
 
-    vkvg_set_rgba(ctx,0.0,0.0,0.1,1.0);
+    vkvg_set_rgba(ctx,0.8,0.8,1.0,1.0);
     vkvg_paint(ctx);
 
     test_line_caps(ctx);
+    //test_line_join(ctx);
 
     //vkvg_test_clip(ctx);
-
+/*
     vkvg_set_rgba (ctx,0.02,0.8,0.3,1.0);
     vkvg_rectangle (ctx,200,200,300,300);
     vkvg_fill (ctx);
 
     test_text(ctx);
-
     vkvg_test_fill2(ctx);
     //vkvg_test_fill(ctx);
 
@@ -710,7 +748,7 @@ int main(int argc, char *argv[]) {
     vkvg_test_curves(ctx);
 
     //test_img_surface(ctx);
-
+*/
     vkvg_destroy(ctx);
     ctx = vkvg_create(surf);