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++;
}
}
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];
_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){
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;
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]);
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);
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);
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);
}
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);
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);
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);
}
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);
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);
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);
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();
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);