From: Jean-Philippe Bruyère Date: Sat, 11 Jul 2020 10:32:49 +0000 (+0200) Subject: path array with only segment lengths instead of start/stop points X-Git-Tag: v0.1-alpha~13 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=ab871c2d4cf48025e982eff8228ce6d57e6756e5;p=jp%2Fvkvg.git path array with only segment lengths instead of start/stop points --- diff --git a/include/vkvg.h b/include/vkvg.h index 28af6cf..81a73f4 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -64,7 +64,8 @@ typedef enum { VKVG_STATUS_INVALID_FORMAT, VKVG_STATUS_INVALID_VISUAL, VKVG_STATUS_FILE_NOT_FOUND, - VKVG_STATUS_INVALID_DASH + VKVG_STATUS_INVALID_DASH, + VKVG_STAtUS_NOT_ENOUGH_POINTS_TO_CLOSE_PATH }vkvg_status_t; typedef enum { diff --git a/src/vkvg_context.c b/src/vkvg_context.c index fbbbf89..eaf7f7f 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -320,19 +320,19 @@ void vkvg_new_path (VkvgContext ctx){ * @param context pointer */ void vkvg_close_path (VkvgContext ctx){ - if (_current_path_is_empty(ctx)){ - ctx->status = VKVG_STATUS_NO_CURRENT_POINT; + //check if at least 3 points are present + if (ctx->pathes[ctx->pathPtr] < 3){ + ctx->status = VKVG_STAtUS_NOT_ENOUGH_POINTS_TO_CLOSE_PATH; return; } - //check if at least 3 points are present - if (ctx->pointCount - (ctx->pathes [ctx->pathPtr-1]&PATH_ELT_MASK) > 2){ - ctx->pathes[ctx->pathPtr] = ctx->pointCount - 1; - ctx->pathes[ctx->pathPtr-1] |= PATH_CLOSED_BIT; - _check_pathes_array(ctx); - ctx->pathPtr += ctx->curvePtr + 1; - ctx->curvePtr = 0; - }else - _finish_path(ctx); + //prevent closing on the same point + if (vec2_equ(ctx->points[ctx->pointCount-1], + ctx->points[ctx->pointCount - ctx->pathes[ctx->pathPtr]])) + _remove_last_point(ctx); + + ctx->pathes[ctx->pathPtr] |= PATH_CLOSED_BIT; + + _finish_path(ctx); } /** * @brief draw line with second point coordinates relative to current point @@ -357,13 +357,12 @@ void vkvg_rel_line_to (VkvgContext ctx, float x, float y){ void vkvg_line_to (VkvgContext ctx, float x, float y) { vec2 p = {x,y}; - if (_current_path_is_empty(ctx)){ - vkvg_move_to(ctx, x,y); - return; - }else if (vec2_equ(_get_current_position(ctx),p)) - return; - - _add_point(ctx,x,y); + if (!_current_path_is_empty (ctx)){ + //prevent adding the same point + if (vec2_equ (_get_current_position (ctx), p)) + return; + } + _add_point (ctx, x, y); } /** * @brief Draw arc in clockwise order following angles of the trigonometric circle. @@ -386,18 +385,19 @@ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, floa float step = _get_arc_step(ctx, radius); float a = a1; - if (_current_path_is_empty(ctx)) - vkvg_move_to(ctx, v.x, v.y); - else + if (_current_path_is_empty(ctx)){ + _set_curve_start (ctx); + _add_point (ctx, v.x, v.y); + }else{ vkvg_line_to(ctx, v.x, v.y); + _set_curve_start (ctx); + } a+=step; if (EQUF(a2, a1)) return; - _set_curve_start (ctx); - while(a < a2){ v.x = cosf(a)*radius + xc; v.y = sinf(a)*radius + yc; @@ -438,10 +438,12 @@ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float float step = _get_arc_step(ctx, radius); float a = a1; - if (_current_path_is_empty(ctx)) - vkvg_move_to(ctx, v.x, v.y); - else { + if (_current_path_is_empty(ctx)){ + _set_curve_start (ctx); + _add_point (ctx, v.x, v.y); + }else{ vkvg_line_to(ctx, v.x, v.y); + _set_curve_start (ctx); } a-=step; @@ -449,8 +451,6 @@ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float if (EQUF(a2, a1)) return; - _set_curve_start (ctx); - while(a > a2){ v.x = cosf(a)*radius + xc; v.y = sinf(a)*radius + yc; @@ -493,16 +493,16 @@ void vkvg_rel_move_to (VkvgContext ctx, float x, float y) void vkvg_move_to (VkvgContext ctx, float x, float y) { _finish_path(ctx); - _start_sub_path(ctx, x, y); + _add_point (ctx, x, y); } void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) { + _set_curve_start (ctx); if (_current_path_is_empty(ctx)) - vkvg_move_to(ctx, x1, y1); + _add_point(ctx, x1, y1); vec2 cp = _get_current_position(ctx); - _set_curve_start (ctx); _recursive_bezier (ctx, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0); /*cp.x = x3; cp.y = y3; @@ -590,7 +590,7 @@ void vkvg_clip_preserve (VkvgContext ctx){ CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); } void vkvg_fill_preserve (VkvgContext ctx){ - if (ctx->pathPtr == 0) //nothing to fill + if (!(ctx->pathPtr || ctx->segmentPtr)) //nothing to fill return; _finish_path(ctx); @@ -718,7 +718,7 @@ void _draw_segment (VkvgContext ctx, float hw, bool isCurve) { } void vkvg_stroke_preserve (VkvgContext ctx) { - if (ctx->pathPtr == 0)//nothing to stroke + if (ctx->pathPtr == 0 && _current_path_is_empty(ctx))//nothing to stroke return; _finish_path(ctx); @@ -728,15 +728,19 @@ void vkvg_stroke_preserve (VkvgContext ctx) curPathPointIdx = lastPathPointIdx = ptrPath = iL = iR = 0; while (ptrPath < ctx->pathPtr){ - uint32_t ptrCurve = 0; + uint32_t ptrSegment = 0, lastSegmentPointIdx = 0; + uint32_t firstPathPointIdx = curPathPointIdx; + uint32_t pathPointCount = ctx->pathes[ptrPath]&PATH_ELT_MASK; + lastPathPointIdx = curPathPointIdx + pathPointCount - 1; + if (_path_has_curves (ctx,ptrPath)) { + ptrSegment = 1; + lastSegmentPointIdx = curPathPointIdx + (ctx->pathes[ptrPath+ptrSegment]&PATH_ELT_MASK)-1; + } VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); - curPathPointIdx = ctx->pathes[ptrPath]&PATH_ELT_MASK; - - LOG(VKVG_LOG_INFO_PATH, "\tPATH: start=%d end=%d", ctx->pathes[ptrPath]&PATH_ELT_MASK, ctx->pathes[ptrPath+1]&PATH_ELT_MASK); - lastPathPointIdx = ctx->pathes[ptrPath+1]&PATH_ELT_MASK; + //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); if (ctx->dashCount > 0) { @@ -760,10 +764,6 @@ void vkvg_stroke_preserve (VkvgContext ctx) iL = lastPathPointIdx; } else if (_path_is_closed(ctx,ptrPath)){ - //prevent closing on the same position, this could be generalize - //to prevent processing of two consecutive point at the same position - if (vec2_equ(ctx->points[curPathPointIdx], ctx->points[lastPathPointIdx])) - lastPathPointIdx--; iL = lastPathPointIdx; }else{ _draw_stoke_cap(ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx], ctx->points[curPathPointIdx+1]), true); @@ -772,20 +772,28 @@ void vkvg_stroke_preserve (VkvgContext ctx) if (_path_has_curves (ctx,ptrPath)) { while (curPathPointIdx < lastPathPointIdx){ - if (ptrPath + ptrCurve + 2 < ctx->pathPtr && (ctx->pathes [ptrPath + 2 + ptrCurve] & PATH_ELT_MASK) == curPathPointIdx){ - uint32_t lastCurvePointIdx = ctx->pathes[ptrPath + 3 + ptrCurve]&PATH_ELT_MASK; - while (curPathPointIdx < lastCurvePointIdx) - _draw_segment(ctx, hw, true); - ptrCurve += 2; - }else - _draw_segment(ctx, hw, false); + + bool curved = ctx->pathes [ptrPath + ptrSegment] & PATH_IS_CURVE_BIT; + if (lastSegmentPointIdx == lastPathPointIdx)//last segment of path, dont draw end point here + lastSegmentPointIdx--; + while (curPathPointIdx <= lastSegmentPointIdx) + _draw_segment(ctx, hw, curved); + + ptrSegment ++; + uint32_t cptSegPts = ctx->pathes [ptrPath + ptrSegment]&PATH_ELT_MASK; + lastSegmentPointIdx = curPathPointIdx + cptSegPts - 1; + if (lastSegmentPointIdx == lastPathPointIdx && cptSegPts == 1) { + //single point last segment + ptrSegment++; + break; + } } }else while (curPathPointIdx < lastPathPointIdx) _draw_segment(ctx, hw, false); if (ctx->dashCount > 0) { if (_path_is_closed(ctx,ptrPath)){ - iR = ctx->pathes[ptrPath] & PATH_ELT_MASK; + iR = firstPathPointIdx; _draw_dashed_segment(ctx, hw, ctx->points[iL++], ctx->points[curPathPointIdx++], ctx->points[iR], false); } if (!dashOn){ @@ -799,7 +807,7 @@ void vkvg_stroke_preserve (VkvgContext ctx) _draw_stoke_cap (ctx, hw, p, normal, false); } } else if (_path_is_closed(ctx,ptrPath)){ - iR = ctx->pathes[ptrPath] & PATH_ELT_MASK; + iR = firstPathPointIdx; float cross = _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], false); VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache [ctx->indCount-6]; @@ -817,7 +825,12 @@ void vkvg_stroke_preserve (VkvgContext ctx) }else _draw_stoke_cap (ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx-1], ctx->points[curPathPointIdx]), false); - ptrPath+=2+ptrCurve; + curPathPointIdx = firstPathPointIdx + pathPointCount; + + if (ptrSegment > 0) + ptrPath += ptrSegment; + else + ptrPath++; } _record_draw_cmd(ctx); } diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 9c01720..1910635 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -72,36 +72,40 @@ void _check_index_cache_size (VkvgContext ctx) { } ctx->indexCache = tmp; } -void _check_pathes_array (VkvgContext ctx){ - if (ctx->sizePathes - ctx->pathPtr - ctx->curvePtr > VKVG_ARRAY_THRESHOLD) - return; +//check host path array size, return true if error. pathPtr is already incremented +bool _check_pathes_array (VkvgContext ctx){ + if (ctx->sizePathes - ctx->pathPtr - ctx->segmentPtr > VKVG_ARRAY_THRESHOLD) + return false; ctx->sizePathes += VKVG_PATHES_SIZE; uint32_t* tmp = (uint32_t*) realloc (ctx->pathes, (size_t)ctx->sizePathes * sizeof(uint32_t)); LOG(VKVG_LOG_DBG_ARRAYS, "resize PATH: new size: %u Ptr: %p -> %p\n", ctx->sizePathes, ctx->pathes, tmp); if (tmp == NULL){ ctx->status = VKVG_STATUS_NO_MEMORY; LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePathes * sizeof(uint32_t)); - ctx->pathPtr = 0 + (ctx->pathPtr % 2); - }else - ctx->pathes = tmp; + _clear_path(ctx); + return true; + } + ctx->pathes = tmp; + return false; } -void _check_point_array (VkvgContext ctx){ +//check host point array size, return true if error +bool _check_point_array (VkvgContext ctx){ if (ctx->sizePoints - ctx->pointCount > VKVG_ARRAY_THRESHOLD) - return; - ctx->sizePoints += VKVG_PATHES_SIZE; + return false; + ctx->sizePoints += VKVG_PTS_SIZE; vec2* tmp = (vec2*) realloc (ctx->points, (size_t)ctx->sizePoints * sizeof(vec2)); LOG(VKVG_LOG_DBG_ARRAYS, "resize Points: new size(point): %u Ptr: %p -> %p\n", ctx->sizePoints, ctx->points, tmp); if (tmp == NULL){ ctx->status = VKVG_STATUS_NO_MEMORY; LOG(VKVG_LOG_ERR, "resize PATH failed: new size(byte): %zu\n", ctx->sizePoints * sizeof(vec2)); - ctx->pointCount = 0; - }else - ctx->points = tmp; + _clear_path (ctx); + return true; + } + ctx->points = tmp; + return false; } -//when empty, ptr is even, else it's odd -//when empty, no current point is defined. bool _current_path_is_empty (VkvgContext ctx) { - return ctx->pathPtr % 2 == 0; + return ctx->pathes [ctx->pathPtr] == 0; } //this function expect that current point exists vec2 _get_current_position (VkvgContext ctx) { @@ -109,14 +113,28 @@ vec2 _get_current_position (VkvgContext ctx) { } //set curve start point and set path has curve bit void _set_curve_start (VkvgContext ctx) { - ctx->pathes[ctx->pathPtr + ctx->curvePtr + 1] = (ctx->pointCount - 1); - ctx->pathes[ctx->pathPtr - 1] |= PATH_HAS_CURVES_BIT; + if (ctx->segmentPtr > 0) { + //check if current segment has points (straight) + if ((ctx->pathes [ctx->pathPtr + ctx->segmentPtr]&PATH_ELT_MASK) > 0) + ctx->segmentPtr++; + }else{ + //not yet segmented path, first segment length is copied + if (ctx->pathes [ctx->pathPtr] > 0){//create first straight segment first + ctx->pathes [ctx->pathPtr + 1] = ctx->pathes [ctx->pathPtr]; + ctx->segmentPtr = 2; + }else + ctx->segmentPtr = 1; + } + _check_pathes_array(ctx); + ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = 0; } -//set curve end point and set path is curve bit +//compute segment length and set is curved bit void _set_curve_end (VkvgContext ctx) { - ctx->pathes [ctx->pathPtr + ctx->curvePtr + 2] = (ctx->pointCount - 1) | PATH_IS_CURVE_BIT; - ctx->curvePtr+=2; + //ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = ctx->pathes [ctx->pathPtr] - ctx->pathes [ctx->pathPtr + ctx->segmentPtr]; + ctx->pathes [ctx->pathPtr + ctx->segmentPtr] |= PATH_IS_CURVE_BIT; + ctx->segmentPtr++; _check_pathes_array(ctx); + ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = 0; } //path start pointed at ptrPath has curve bit bool _path_has_curves (VkvgContext ctx, uint32_t ptrPath) { @@ -124,33 +142,56 @@ bool _path_has_curves (VkvgContext ctx, uint32_t ptrPath) { } //this function expect that current path is empty void _start_sub_path (VkvgContext ctx, float x, float y) { - //set start to current idx in point array - ctx->pathes[ctx->pathPtr] = ctx->pointCount; - _add_point(ctx, x, y); - _check_pathes_array(ctx); - ctx->pathPtr++; + _add_point (ctx, x, y); } void _finish_path (VkvgContext ctx){ - if (_current_path_is_empty(ctx)) + if (ctx->pathes [ctx->pathPtr] == 0)//empty return; - if (ctx->pathes[ctx->pathPtr-1] == ctx->pointCount - 1){ + if ((ctx->pathes [ctx->pathPtr]&PATH_ELT_MASK) < 2){ //only current pos is in path - ctx->pathPtr--; + ctx->pointCount -= ctx->pathes[ctx->pathPtr];//what about the bounds? + ctx->pathes[ctx->pathPtr] = 0; + ctx->segmentPtr = 0; return; } - //set end index of current path to last point in points array - ctx->pathes[ctx->pathPtr] = ctx->pointCount - 1; - _check_pathes_array(ctx); - ctx->pathPtr += ctx->curvePtr + 1; - ctx->curvePtr = 0; + if (ctx->segmentPtr > 0) { + ctx->pathes[ctx->pathPtr] |= PATH_HAS_CURVES_BIT; + //if last segment is not a curve and point count > 0 + if ((ctx->pathes[ctx->pathPtr+ctx->segmentPtr]&PATH_IS_CURVE_BIT)==0 && + (ctx->pathes[ctx->pathPtr+ctx->segmentPtr]&PATH_ELT_MASK) > 0) + ctx->segmentPtr++;//current segment has to be included + ctx->pathPtr += ctx->segmentPtr; + }else + ctx->pathPtr ++; + + if (_check_pathes_array(ctx)) + return; + + ctx->pathes[ctx->pathPtr] = 0; + ctx->segmentPtr = 0; } +//clear path datas in context void _clear_path (VkvgContext ctx){ ctx->pathPtr = 0; + ctx->pathes [ctx->pathPtr] = 0; ctx->pointCount = 0; - ctx->curvePtr = 0; + ctx->segmentPtr = 0; _resetMinMax(ctx); } +void _remove_last_point (VkvgContext ctx){ + ctx->pathes[ctx->pathPtr]--; + ctx->pointCount--; + if (ctx->segmentPtr > 0){//if path is segmented + if (!ctx->pathes [ctx->pathPtr + ctx->segmentPtr])//if current segment is empty + ctx->segmentPtr--; + ctx->pathes [ctx->pathPtr + ctx->segmentPtr]--;//decrement last segment point count + if ((ctx->pathes [ctx->pathPtr + ctx->segmentPtr]&PATH_ELT_MASK) == 0)//if no point left (was only one) + ctx->pathes [ctx->pathPtr + ctx->segmentPtr] = 0;//reset current segment + else if (ctx->pathes [ctx->pathPtr + ctx->segmentPtr]&PATH_IS_CURVE_BIT)//if segment is a curve + ctx->segmentPtr++;//then segPtr has to be forwarded to new segment + } +} bool _path_is_closed (VkvgContext ctx, uint32_t ptrPath){ return ctx->pathes[ptrPath] & PATH_CLOSED_BIT; } @@ -159,10 +200,14 @@ void _resetMinMax (VkvgContext ctx) { ctx->xMax = ctx->yMax = FLT_MIN; } void _add_point (VkvgContext ctx, float x, float y){ - ctx->points[ctx->pointCount] = (vec2){x,y}; - ctx->pointCount++; + if (_check_point_array(ctx)) + return; - _check_point_array(ctx); + ctx->points[ctx->pointCount] = (vec2){x,y}; + ctx->pointCount++;//total point count of pathes, (for array bounds check) + ctx->pathes[ctx->pathPtr]++;//total point count in path + if (ctx->segmentPtr > 0) + ctx->pathes[ctx->pathPtr + ctx->segmentPtr]++;//total point count in path's segment //bounds are computed here to scissor the painting operation //that speed up fill drastically. @@ -1033,53 +1078,53 @@ void _poly_fill (VkvgContext ctx){ CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelinePolyFill); - uint32_t ptrPath = 0; Vertex v = {{0},{0,0,-1}}; + uint32_t ptrPath = 0; + uint32_t firstPtIdx = 0; while (ptrPath < ctx->pathPtr){ - if (ctx->pathes[ptrPath+1]&PATH_IS_CURVE_BIT){ - ptrPath += 2; - continue; - } //close path ctx->pathes[ptrPath] |= PATH_CLOSED_BIT; - uint32_t firstPtIdx = ctx->pathes [ptrPath] & PATH_ELT_MASK; - uint32_t lastPtIdx = ctx->pathes [ptrPath+1] & PATH_ELT_MASK; - uint32_t pathPointCount = lastPtIdx - firstPtIdx + 1; - uint32_t firstVertIdx = ctx->vertCount; + uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK; + + VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)ctx->vertCount; for (uint32_t i = 0; i < pathPointCount; i++) { v.pos = ctx->points [i+firstPtIdx]; - ctx->vertexCache[ctx->vertCount] = v; - ctx->vertCount++; - + ctx->vertexCache[ctx->vertCount++] = v; _check_vertex_cache_size(ctx); } LOG(VKVG_LOG_INFO_PATH, "\tpoly fill: point count = %d; 1st vert = %d; vert count = %d\n", pathPointCount, firstVertIdx, ctx->vertCount - firstVertIdx); CmdDraw (ctx->cmd, pathPointCount, 1, firstVertIdx , 0); - ptrPath+=2; + firstPtIdx += pathPointCount; + + if (_path_has_curves (ctx, ptrPath)) { + //skip segments lengths used in stroke + ptrPath++; + uint32_t totPts = 0; + while (totPts < pathPointCount) + totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK); + }else + ptrPath++; } ctx->curVertOffset = ctx->vertCount; } void _fill_ec (VkvgContext ctx){ - uint32_t ptrPath = 0;; Vertex v = {0}; v.uv.z = -1; + uint32_t ptrPath = 0; + uint32_t firstPtIdx = 0; + while (ptrPath < ctx->pathPtr){ - if (ctx->pathes[ptrPath+1] & PATH_IS_CURVE_BIT){ - ptrPath += 2; - continue; - } ctx->pathes[ptrPath] |= PATH_CLOSED_BIT;//close path - uint32_t firstPtIdx = ctx->pathes[ptrPath] &PATH_ELT_MASK; - uint32_t lastPtIdx = ctx->pathes[ptrPath+1]&PATH_ELT_MASK; - uint32_t pathPointCount = lastPtIdx - firstPtIdx + 1; - VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); + uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK; + + VKVG_IBO_INDEX_TYPE firstVertIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); ear_clip_point* ecps = (ear_clip_point*)malloc(pathPointCount*sizeof(ear_clip_point)); uint32_t ecps_count = pathPointCount; @@ -1135,7 +1180,15 @@ void _fill_ec (VkvgContext ctx){ if (ecps_count == 3) _add_triangle_indices(ctx, ecp_current->next->idx, ecp_current->idx, ecp_current->next->next->idx); - ptrPath+=2; + firstPtIdx += pathPointCount; + if (_path_has_curves (ctx, ptrPath)) { + //skip segments lengths used in stroke + ptrPath++; + uint32_t totPts = 0; + while (totPts < pathPointCount) + totPts += (ctx->pathes[ptrPath++] & PATH_ELT_MASK); + }else + ptrPath++; free (ecps); } _record_draw_cmd(ctx); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 5e5b548..6751090 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -121,17 +121,12 @@ typedef struct _vkvg_context_t { uint32_t sizePoints; //reserved size uint32_t pointCount; //effective points count - //pathes array is a list of couple (start,end) point idx refering to point array - //it split points list in subpathes and tell if path is closed. - uint32_t pathPtr; //pointer in the path array, even=start point;odd=end point + //pathes array is a list of point count per segment + uint32_t pathPtr; //pointer in the path array uint32_t* pathes; uint32_t sizePathes; - //if current path contains curves, curve's start/end points are store next to the path start/stop - //curve start point = pathPtr + curvePtr - //when closing of finishing path, pathPtr is incremented by 1 + pathPtr - //note:number of pathes can no longer be computed from pathPtr/2, the array contains now curves datas - uint32_t curvePtr; + uint32_t segmentPtr; //current segment count in current path having curves float lineWidth; uint32_t dashCount; //value count in dash array, 0 if dash not set. @@ -169,12 +164,13 @@ void _check_flush_needed (VkvgContext ctx); void _check_vertex_cache_size(VkvgContext ctx); void _resize_vertex_cache (VkvgContext ctx, uint32_t newSize); void _check_index_cache_size(VkvgContext ctx); -void _check_pathes_array (VkvgContext ctx); +bool _check_pathes_array (VkvgContext ctx); bool _current_path_is_empty (VkvgContext ctx); void _start_sub_path (VkvgContext ctx, float x, float y); void _finish_path (VkvgContext ctx); void _clear_path (VkvgContext ctx); +void _remove_last_point (VkvgContext ctx); bool _path_is_closed (VkvgContext ctx, uint32_t ptrPath); void _set_curve_start (VkvgContext ctx); void _set_curve_end (VkvgContext ctx); diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index 1674e05..ec7ccde 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -44,11 +44,11 @@ #endif*/ #define PATH_CLOSED_BIT 0x80000000 /* most significant bit of path elmts is closed/open path state */ -#define PATH_HAS_CURVES_BIT 0x40000000 /* 2d most significant bit of path elmts start = true if curve data are present, - stored to avoid emiting join in curves */ +#define PATH_HAS_CURVES_BIT 0x40000000 /* 2d most significant bit of path elmts if curve data are present, + stored to avoid emiting joins in curves */ #define PATH_IS_CURVE_BIT 0x80000000 /* most significant bit of path elmts end mark curves data in path array */ #define PATH_IS_CONCAVE_BIT 0x40000000 /* 2d most significant bit of path elmts end = true if path is simple concave - triangulation for fill may be simplified*/ + triangulation for fill may be simplified (not implemented)*/ #define PATH_ELT_MASK 0x3FFFFFFF /* Bit mask for fetching path element value */ #define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c)))