if (_current_path_is_empty(ctx)){
_set_curve_start (ctx);
_add_point (ctx, v.x, v.y);
+ if (!ctx->pathPtr)
+ ctx->simpleConvex = true;
+ else
+ ctx->simpleConvex = false;
}else{
_line_to(ctx, v.x, v.y);
_set_curve_start (ctx);
+ ctx->simpleConvex = false;
}
a+=step;
if (_current_path_is_empty(ctx)){
_set_curve_start (ctx);
_add_point (ctx, v.x, v.y);
+ if (!ctx->pathPtr)
+ ctx->simpleConvex = true;
+ else
+ ctx->simpleConvex = false;
}else{
_line_to(ctx, v.x, v.y);
_set_curve_start (ctx);
+ ctx->simpleConvex = false;
}
a-=step;
*x = cp.x;
*y = cp.y;
}
+void _curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
+ //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)))
+ return;
+ }
+ _set_curve_start (ctx);
+ if (_current_path_is_empty(ctx))
+ _add_point(ctx, x1, y1);
+
+ vec2 cp = _get_current_position(ctx);
+
+ //compute dyn distanceTolerance depending on current scale
+ float sx = 1, sy = 1;
+ vkvg_matrix_get_scale (&ctx->pushConsts.mat, &sx, &sy);
+ float distanceTolerance = fabs(1.0f / fmaxf(sx,sy));
+
+ _recursive_bezier (ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0);
+ /*cp.x = x3;
+ cp.y = y3;
+ if (!vec2_equ(ctx->points[ctx->pointCount-1],cp))*/
+ _add_point(ctx,x3,y3);
+ _set_curve_end (ctx);
+}
const double quadraticFact = 2.0/3.0;
void _quadratic_to (VkvgContext ctx, float x1, float y1, float x2, float y2) {
float x0, y0;
y0 = y1;
} else
vkvg_get_current_point (ctx, &x0, &y0);
- vkvg_curve_to (ctx,
+ _curve_to (ctx,
x0 + (x1 - x0) * quadraticFact,
y0 + (y1 - y0) * quadraticFact,
x2 + (x1 - x2) * quadraticFact,
vec2 cp = _get_current_position(ctx);
_quadratic_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2);
}
-void _curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
- //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)))
- return;
- }
- _set_curve_start (ctx);
- if (_current_path_is_empty(ctx))
- _add_point(ctx, x1, y1);
-
- vec2 cp = _get_current_position(ctx);
-
- //compute dyn distanceTolerance depending on current scale
- float sx = 1, sy = 1;
- vkvg_matrix_get_scale (&ctx->pushConsts.mat, &sx, &sy);
- float distanceTolerance = fabs(1.0f / fmaxf(sx,sy));
-
- _recursive_bezier (ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0);
- /*cp.x = x3;
- cp.y = y3;
- if (!vec2_equ(ctx->points[ctx->pointCount-1],cp))*/
- _add_point(ctx,x3,y3);
- _set_curve_end (ctx);
-}
void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) {
if (ctx->status)
return;
_add_point (ctx, x + w, y + h);
_add_point (ctx, x, y + h);
- ctx->pathes[ctx->pathPtr] |= PATH_CLOSED_BIT;
+ ctx->pathes[ctx->pathPtr] |= (PATH_CLOSED_BIT|PATH_IS_CONVEX_BIT);
_finish_path(ctx);
return VKVG_STATUS_SUCCESS;
-/*
+/*
* Copyright (c) 2018-2022 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
LOG(VKVG_LOG_INFO_PATH, "PATH: points count=%10d\n", ctx->pathes[ctx->pathPtr]&PATH_ELT_MASK);
+ if (ctx->pathPtr == 0 && ctx->simpleConvex)
+ ctx->pathes[0] |= PATH_IS_CONVEX_BIT;
+
if (ctx->segmentPtr > 0) {
ctx->pathes[ctx->pathPtr] |= PATH_HAS_CURVES_BIT;
//if last segment is not a curve and point count > 0
ctx->pathes[ctx->pathPtr] = 0;
ctx->segmentPtr = 0;
ctx->subpathCount++;
+ ctx->simpleConvex = false;
}
//clear path datas in context
void _clear_path (VkvgContext ctx){
ctx->pointCount = 0;
ctx->segmentPtr = 0;
ctx->subpathCount = 0;
+ ctx->simpleConvex = false;
}
void _remove_last_point (VkvgContext ctx){
ctx->pathes[ctx->pathPtr]--;
_check_index_cache_size(ctx);
LOG(VKVG_LOG_INFO_IBO, "Triangle IDX: %d %d %d (indCount=%d)\n", i0,i1,i2,ctx->indCount);
}
+void _add_triangle_indices_unchecked (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];
+ inds[0] = i0;
+ inds[1] = i1;
+ inds[2] = i2;
+ ctx->indCount+=3;
+
+ 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;
}
_add_point (ctx, x, y);
+ ctx->simpleConvex = false;
}
void _elliptic_arc (VkvgContext ctx, float x1, float y1, float x2, float y2, bool largeArc, bool counterClockWise, float _rx, float _ry, float phi) {
if (ctx->status)
if (_current_path_is_empty(ctx)){
_set_curve_start (ctx);
_add_point (ctx, xy.x, xy.y);
+ ctx->simpleConvex = true;
}else{
_line_to(ctx, xy.x, xy.y);
_set_curve_start (ctx);
+ ctx->simpleConvex = false;
}
_set_curve_start (ctx);
uint32_t ptrPath = 0;
uint32_t firstPtIdx = 0;
+ if (ctx->pathPtr == 1 && ctx->pathes[0] & PATH_IS_CONVEX_BIT) {
+ //simple concave rectangle or circle
+ VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
+ uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK;
+
+ _ensure_vertex_cache_size(ctx, pathPointCount);
+ _ensure_index_cache_size(ctx, (pathPointCount-2)*3);
+
+ VKVG_IBO_INDEX_TYPE i = 0;
+ while (i < 2){
+ v.pos = ctx->points [i++];
+ _set_vertex (ctx, ctx->vertCount++, v);
+ }
+ while (i < pathPointCount){
+ v.pos = ctx->points [i];
+ _set_vertex (ctx, ctx->vertCount++, v);
+ _add_triangle_indices_unchecked(ctx, firstVertIdx, firstVertIdx + i - 1, firstVertIdx + i);
+ i++;
+ }
+ return;
+ }
+
GLUtesselator *tess = gluNewTess();
gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);