void vkvg_new_sub_path (VkvgContext ctx){
if (ctx->status)
return;
+
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: new_sub_path:\n");
+
_finish_path(ctx);
}
void vkvg_new_path (VkvgContext ctx){
if (ctx->status)
return;
+
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: new_path:\n");
+
_clear_path(ctx);
}
void vkvg_close_path (VkvgContext ctx){
if (ctx->status)
return;
+
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: close_path:\n");
+
if (ctx->pathes[ctx->pathPtr] & PATH_CLOSED_BIT) //already closed
return;
//check if at least 3 points are present
void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy){
if (ctx->status)
return;
+
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_line_to:\n");
+
if (_current_path_is_empty(ctx))
_add_point(ctx, 0, 0);
vec2 cp = _get_current_position(ctx);
{
if (ctx->status)
return;
+
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: line_to:\n");
+
vec2 p = {x,y};
if (!_current_path_is_empty (ctx)){
//prevent adding the same point
void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2){
if (ctx->status)
return;
+
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: arc:\n");
+
while (a2 < a1)//positive arc must have a1<a2
a2 += 2.f*M_PIF;
void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: arc_neg:\n");
while (a2 > a1)
a2 -= 2.f*M_PIF;
if (a1 - a2 > a1 + 2.f * M_PIF) //limit arc to 2PI
{
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_mote_to:\n");
if (_current_path_is_empty(ctx))
_add_point(ctx, 0, 0);
vec2 cp = _get_current_position(ctx);
{
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: move_to:\n");
_finish_path(ctx);
_add_point (ctx, x, y);
}
void vkvg_rel_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_quadratic_to:\n");
vec2 cp = _get_current_position(ctx);
vkvg_quadratic_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2);
}
void vkvg_quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: quadratic_to:\n");
float x0, y0;
if (_current_path_is_empty(ctx)) {
void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: curve_to:\n");
//prevent running _recursive_bezier when all 4 curve points are equal
if (EQUF(x1,x2) && EQUF(x2,x3) && EQUF(y1,y2) && EQUF(y2,y3)) {
if (_current_path_is_empty(ctx) || (EQUF(_get_current_position(ctx).x,x1) && EQUF(_get_current_position(ctx).y,y1)))
void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_curve_to:\n");
vec2 cp = _get_current_position(ctx);
vkvg_curve_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2, cp.x + x3, cp.y + y3);
}
void vkvg_fill_rectangle (VkvgContext ctx, float x, float y, float w, float h){
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: fill_rectangle:\n");
_vao_add_rectangle (ctx,x,y,w,h);
//_record_draw_cmd(ctx);
}
vkvg_status_t vkvg_rectangle (VkvgContext ctx, float x, float y, float w, float h){
if (ctx->status)
return ctx->status;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: rectangle:\n");
_finish_path (ctx);
if (w <= 0 || h <= 0)
vkvg_status_t vkvg_rounded_rectangle (VkvgContext ctx, float x, float y, float w, float h, float radius){
if (ctx->status)
return ctx->status;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: rounded_rectangle:\n");
_finish_path (ctx);
if (w <= 0 || h <= 0)
return VKVG_STATUS_SUCCESS;
}
void vkvg_rounded_rectangle2 (VkvgContext ctx, float x, float y, float w, float h, float rx, float ry){
+ if (ctx->status)
+ return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: rounded_rectangle2:\n");
vkvg_move_to (ctx, x+rx, y);
vkvg_line_to (ctx, x+w-rx, y);
vkvg_elliptic_arc_to(ctx, x+w, y+ry, false, true, rx, ry, 0);
if (!ctx->pathPtr)//nothing to fill
return;
- LOG(VKVG_LOG_INFO, "FILL: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
+ LOG(VKVG_LOG_INFO, "FILL: ctx = %p; path cpt = %d;\n", ctx, ctx->subpathCount);
if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){
_emit_draw_cmd_undrawn_vertices(ctx);
str.firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
- //LOG(VKVG_LOG_INFO_PATH, "\tPATH: start=%d end=%d", ctx->pathes[ptrPath]&PATH_ELT_MASK, ctx->pathes[ptrPath+1]&PATH_ELT_MASK);
- LOG(VKVG_LOG_INFO_PATH, "end = %d\n", lastPathPointIdx);
+ //LOG(VKVG_LOG_INFO_PATH, "\tPATH: points count=%10d end point idx=%10d", ctx->pathes[ptrPath]&PATH_ELT_MASK, lastPathPointIdx);
if (ctx->dashCount > 0) {
//init dash stroke
void vkvg_show_text (VkvgContext ctx, const char* text){
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: show_text:\n");
//_ensure_renderpass_is_started(ctx);
_show_text (ctx, text);
//_flush_undrawn_vertices (ctx);
void vkvg_translate (VkvgContext ctx, float dx, float dy){
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: translate:\n");
_emit_draw_cmd_undrawn_vertices(ctx);
vkvg_matrix_translate (&ctx->pushConsts.mat, dx, dy);
_set_mat_inv_and_vkCmdPush (ctx);
void vkvg_scale (VkvgContext ctx, float sx, float sy){
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: scale:\n");
_emit_draw_cmd_undrawn_vertices(ctx);
vkvg_matrix_scale (&ctx->pushConsts.mat, sx, sy);
_set_mat_inv_and_vkCmdPush (ctx);
void vkvg_rotate (VkvgContext ctx, float radians){
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: rotate:\n");
_emit_draw_cmd_undrawn_vertices(ctx);
vkvg_matrix_rotate (&ctx->pushConsts.mat, radians);
_set_mat_inv_and_vkCmdPush (ctx);
void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: transform:\n");
_emit_draw_cmd_undrawn_vertices(ctx);
vkvg_matrix_t res;
vkvg_matrix_multiply (&res, &ctx->pushConsts.mat, matrix);
void vkvg_identity_matrix (VkvgContext ctx) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: identity_matrix:\n");
_emit_draw_cmd_undrawn_vertices(ctx);
vkvg_matrix_t im = VKVG_IDENTITY_MATRIX;
ctx->pushConsts.mat = im;
void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix){
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: set_matrix:\n");
_emit_draw_cmd_undrawn_vertices(ctx);
ctx->pushConsts.mat = (*matrix);
_set_mat_inv_and_vkCmdPush (ctx);
}
void vkvg_elliptic_arc_to (VkvgContext ctx, float x2, float y2, bool largeArc, bool counterClockWise, float rx, float ry, float phi) {
+ if (ctx->status)
+ return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: elliptic_arc_to:\n");
float x1, y1;
vkvg_get_current_point(ctx, &x1, &y1);
_elliptic_arc(ctx, x1, y1, x2, y2, largeArc, counterClockWise, rx, ry, phi);
}
void vkvg_rel_elliptic_arc_to (VkvgContext ctx, float x2, float y2, bool largeArc, bool counterClockWise, float rx, float ry, float phi) {
+ if (ctx->status)
+ return;
+ LOG(VKVG_LOG_INFO_CMD, "\tCMD: rel_elliptic_arc_to: x2:%10.5f y2:%10.5f large:%d sweep:%d rx:%10.5f ry:%10.5f phi:%10.5f \n", x2,y2,largeArc,counterClockWise,rx,ry,phi);
+
float x1, y1;
vkvg_get_current_point(ctx, &x1, &y1);
_elliptic_arc(ctx, x1, y1, x2+x1, y2+y1, largeArc, counterClockWise, rx, ry, phi);
void vkvg_ellipse (VkvgContext ctx, float radiusX, float radiusY, float x, float y, float rotationAngle) {
if (ctx->status)
return;
+ LOG(VKVG_LOG_INFO_CMD, "CMD: ellipse:\n");
float width_two_thirds = radiusX * 4 / 3;
return;
}
+ LOG(VKVG_LOG_INFO_PATH, "PATH: points count=%10d\n", ctx->pathes[ctx->pathPtr]&PATH_ELT_MASK);
+
if (ctx->segmentPtr > 0) {
ctx->pathes[ctx->pathPtr] |= PATH_HAS_CURVES_BIT;
//if last segment is not a curve and point count > 0
}
float _get_arc_step (VkvgContext ctx, float radius) {
float dx = radius, dy = radius;
- vkvg_matrix_transform_point (&ctx->pushConsts.mat, &dx, &dy);
+ vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy);
float r = fabsf(fmaxf(dx,dy));
- if (r < 3.0f)
+ /*if (r < 3.0f)
return asinf (1.0f / r) * 0.25f;
- return asinf (1.0f / r) * 1.5f * sqrtf(r);
+ return asinf (1.0f / r) * 1.5f * sqrtf(r);*/
+ return M_PI / (r * 1.5f);
}
void _create_gradient_buff (VkvgContext ctx){
vkvg_buffer_create (ctx->pSurf->dev,
pVert->pos.y = y;
pVert->color = ctx->curColor;
pVert->uv.z = -1;
+ LOG(VKVG_LOG_INFO_VBO, "Add Vertexf %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n", ctx->vertCount, pVert->pos.x, pVert->pos.y, pVert->uv.x, pVert->uv.y, pVert->uv.z, pVert->color);
ctx->vertCount++;
-
_check_vertex_cache_size(ctx);
}
void _add_vertex(VkvgContext ctx, Vertex v){
ctx->vertexCache[ctx->vertCount] = v;
+ LOG(VKVG_LOG_INFO_VBO, "Add Vertex %10d: pos:(%10.4f, %10.4f) uv:(%10.4f,%10.4f,%10.4f) color:0x%.8x \n", ctx->vertCount, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.uv.z, v.color);
ctx->vertCount++;
-
_check_vertex_cache_size(ctx);
}
void _set_vertex(VkvgContext ctx, uint32_t idx, Vertex v){
ctx->indCount+=6;
_check_index_cache_size(ctx);
- LOG(VKVG_LOG_INFO, "Rectangle IDX: %d %d %d | %d %d %d (count=%d)\n", inds[0], inds[1], inds[2], inds[3], inds[4], inds[5], ctx->indCount);
+ LOG(VKVG_LOG_INFO_IBO, "Rectangle IDX: %d %d %d | %d %d %d (count=%d)\n", inds[0], inds[1], inds[2], inds[3], inds[4], inds[5], ctx->indCount);
}
void _add_triangle_indices(VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2){
VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache[ctx->indCount];
ctx->indCount+=3;
_check_index_cache_size(ctx);
- LOG(VKVG_LOG_INFO, "Triangle IDX: %d %d %d (indCount=%d)\n", i0,i1,i2,ctx->indCount);
+ LOG(VKVG_LOG_INFO_IBO, "Triangle IDX: %d %d %d (indCount=%d)\n", i0,i1,i2,ctx->indCount);
}
void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, float height){
Vertex v[4] =
return false;
vec2 v0n = vec2_div_s (v0, length_v0);
vec2 v1n = vec2_div_s (v1, length_v1);
+ float dot = vec2_dot (v0n, v1n);
+ float det = v0n.x * v1n.y - v0n.y * v1n.x;
+ if (EQUF(dot,1.0f))
+ return false;
+
+ if (EQUF(dot,-1.0f)) {
+ vec2 vPerp = vec2_mult_s(vec2_perp (v0n), hw);
+
+ VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+
+ v.pos = vec2_add(p0, vPerp);
+ _add_vertex(ctx, v);
+ v.pos = vec2_sub(p0, vPerp);
+ _add_vertex(ctx, v);
+
+ _add_triangle_indices(ctx, idx, idx+1, idx+2);
+ _add_triangle_indices(ctx, idx, idx+2, idx+3);
+ return true;
+ }
+
vec2 bisec_n = vec2_norm(vec2_add(v0n,v1n));
- float dot = vec2_dot (v0n, v1n);
float alpha = acosf(dot);
- float det = v0n.x * v1n.y - v0n.y * v1n.x;
- if (EQUF(dot,1.0f))
- return false;
if (det<0)
alpha = -alpha;
double theta = sa;
double ea = sa + delta_theta;
- float step = _get_arc_step(ctx, fminf (rx, ry))*0.1f;
+ float step = fmaxf(0.0001f, fminf(M_PI, _get_arc_step(ctx, fminf (rx, ry))*0.1f));
p = (vec2) {
rx * cosf (theta),
int *tris_out;
int nverts, ntris;
+ LOG(VKVG_LOG_INFO, "glutess: ctx = %p; point cpt = %d;\n", ctx, ctx->pointCount);
+
tessellate(&coordinates_out, &nverts,
&tris_out, &ntris,
contours_array, contours_array + contours_size);