From: Jean-Philippe Bruyère Date: Thu, 19 Apr 2018 18:19:48 +0000 (+0200) Subject: line join basis, try to cover every angles for line but, missing triangle when normal... X-Git-Tag: v0.1-alpha~144 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=3fee7926cb1d061dcb8ffa6359966ccf552d0b7a;p=jp%2Fvkvg.git line join basis, try to cover every angles for line but, missing triangle when normal x<0 et y<0 --- diff --git a/include/vkvg.h b/include/vkvg.h index b520c41..735a1ab 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -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); diff --git a/src/vectors.c b/src/vectors.c index 3bf377c..fdef0af 100644 --- a/src/vectors.c +++ b/src/vectors.c @@ -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; +} diff --git a/src/vectors.h b/src/vectors.h index 18a50df..05657f8 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -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 diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 1047c3c..c063a50 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -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); } diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index ca028d8..49a7aca 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -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) { diff --git a/src/vkvg_matrix.c b/src/vkvg_matrix.c index bcfeb11..e0084a0 100644 --- a/src/vkvg_matrix.c +++ b/src/vkvg_matrix.c @@ -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 + */ + #include "vkvg_matrix.h" #define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */ diff --git a/tests/test1.c b/tests/test1.c index 927f09a..39fc6ca 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -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);