From: Jean-Philippe Bruyère Date: Mon, 9 Aug 2021 23:27:05 +0000 (+0200) Subject: vkvg api float->double X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=a27433e1513d92dbffa6edee1fbba19650022f6b;p=jp%2Fvkvg.git vkvg api float->double --- diff --git a/include/vkvg.h b/include/vkvg.h index a97f2d1..790a624 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -451,7 +451,7 @@ void vkvg_matrix_multiply (vkvg_matrix_t *result, const vkvg_matrix_t *a, const * @param dy Y component of a distance vector. An in/out parameter */ vkvg_public -void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, float *dy); +void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, double* dx, double* dy); /** * @brief transform point * @@ -461,7 +461,7 @@ void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, flo * @param y Y position. An in/out parameter */ vkvg_public -void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *y); +void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, double* x, double* y); /** * @brief invert matrix * @@ -825,7 +825,7 @@ void vkvg_new_sub_path (VkvgContext ctx); * @param y aboslute y coordinate of second point */ vkvg_public -void vkvg_line_to (VkvgContext ctx, float x, float y); +void vkvg_line_to (VkvgContext ctx, double x, double y); /** * @brief Add a line to the current path from the current point to the coordinate relative to it. * @@ -837,7 +837,7 @@ void vkvg_line_to (VkvgContext ctx, float x, float y); * @param dy delta y */ vkvg_public -void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy); +void vkvg_rel_line_to (VkvgContext ctx, double dx, double dy); /** * @brief Move the context pen to the position given in argument. * @@ -851,7 +851,7 @@ void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy); * @param y new y position of the pen */ vkvg_public -void vkvg_move_to (VkvgContext ctx, float x, float y); +void vkvg_move_to (VkvgContext ctx, double x, double y); /** * @brief Move the context pen relative to the current point. * @@ -864,7 +864,7 @@ void vkvg_move_to (VkvgContext ctx, float x, float y); * @param y delta in the vertical direction. */ vkvg_public -void vkvg_rel_move_to (VkvgContext ctx, float x, float y); +void vkvg_rel_move_to (VkvgContext ctx, double x, double y); /** * @brief Adds a circular arc of the given radius to the current path. * @@ -889,7 +889,7 @@ void vkvg_rel_move_to (VkvgContext ctx, float x, float y); * @param a2 end angle in radians of the arc to draw. */ vkvg_public -void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2); +void vkvg_arc (VkvgContext ctx, double xc, double yc, double radius, double a1, double a2); /** * @brief Add a circular arc in counter clockwise order to the current path. * @@ -907,7 +907,7 @@ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, floa * @param a2 end angle in radians of the arc to draw. */ vkvg_public -void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2); +void vkvg_arc_negative (VkvgContext ctx, double xc, double yc, double radius, double a1, double a2); /** * @brief Adds a cubic Bézier spline to the current path. * @@ -924,7 +924,7 @@ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float * @param y3 The Y coordinate of the end of the curve. */ vkvg_public -void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3); +void vkvg_curve_to (VkvgContext ctx, double x1, double y1, double x2, double y2, double x3, double y3); /** * @brief Add an axis aligned rectangle subpath to the current path. * @@ -936,7 +936,7 @@ void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, flo * @param h The height in pixel of the rectangle to draw. */ vkvg_public -void vkvg_rectangle(VkvgContext ctx, float x, float y, float w, float h); +void vkvg_rectangle(VkvgContext ctx, double x, double y, double w, double h); /** * @brief * @@ -947,7 +947,7 @@ void vkvg_rectangle(VkvgContext ctx, float x, float y, float w, float h); * @param h */ vkvg_public -void vkvg_fill_rectangle (VkvgContext ctx, float x, float y, float w, float h); +void vkvg_fill_rectangle (VkvgContext ctx, double x, double y, double w, double h); /** * @brief * @@ -1048,7 +1048,7 @@ void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b); * @param width new current line width for the context. */ vkvg_public -void vkvg_set_line_width (VkvgContext ctx, float width); +void vkvg_set_line_width (VkvgContext ctx, double width); /** * @brief set line terminations * @@ -1117,7 +1117,7 @@ void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr); * @param offset an offset into the dash pattern at which the stroke should start. */ vkvg_public -void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset); +void vkvg_set_dash (VkvgContext ctx, const double* dashes, uint32_t num_dashes, double offset); /** * @brief get current dash settings. * @@ -1130,7 +1130,7 @@ void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, f * @param offset[out] return value for the current dash offset */ vkvg_public -void vkvg_get_dash (VkvgContext ctx, const float *dashes, uint32_t* num_dashes, float* offset); +void vkvg_get_dash (VkvgContext ctx, const double* dashes, uint32_t* num_dashes, double* offset); /** * @brief get current line width diff --git a/src/vectors.h b/src/vectors.h index 3a04255..e0699e8 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -33,9 +33,12 @@ typedef union { }; }vec2; -typedef struct { - double x; - double y; +typedef union { + __m128d raw;// __attribute__ ((vector_size (16))); + struct { + double x; + double y; + }; }vec2d; typedef struct { @@ -76,7 +79,6 @@ typedef struct { int16_t x; int16_t y; }vec2i16; - // compute length of float vector 2d vkvg_inline float vec2_length(vec2 v){ return sqrtf (v.x*v.x + v.y*v.y); @@ -124,7 +126,8 @@ vkvg_inline vec2 vec2_div(vec2 a, float m){ return (vec2){a.x/m,a.y/m}; } vkvg_inline vec2d vec2d_div(vec2d a, double m){ - return (vec2d){a.x/m,a.y/m}; + return (vec2d)_mm_div_pd (a.raw, _mm_set_pd1 (m)); + //return (vec2d){a.x/m,a.y/m}; } // multiply 2d vector by scalar vkvg_inline vec2 vec2_mult(vec2 a, float m){ @@ -148,7 +151,8 @@ vkvg_inline vec2 vec2_add (vec2 a, vec2 b){ } // compute sum of two double precision vectors vkvg_inline vec2d vec2d_add (vec2d a, vec2d b){ - return (vec2d){a.x + b.x, a.y + b.y}; + return (vec2d)_mm_add_pd (a.raw, b.raw); + //return (vec2d){a.x + b.x, a.y + b.y}; } // compute subbstraction of two single precision vectors vkvg_inline vec2 vec2_sub (vec2 a, vec2 b){ @@ -156,12 +160,17 @@ vkvg_inline vec2 vec2_sub (vec2 a, vec2 b){ } // compute subbstraction of two double precision vectors vkvg_inline vec2d vec2d_sub (vec2d a, vec2d b){ - return (vec2d){a.x - b.x, a.y - b.y}; + return (vec2d)_mm_sub_pd (a.raw, b.raw); + //return (vec2d){a.x - b.x, a.y - b.y}; } // test equality of two single precision vectors vkvg_inline bool vec2_equ (vec2 a, vec2 b){ return (EQUF(a.x,b.x)&EQUF(a.y,b.y)); } +vkvg_inline bool vec2d_equ (vec2d a, vec2d b){ + return (EQU(a.x,b.x)&EQU(a.y,b.y)); +} + // compute opposite of single precision vector vkvg_inline void vec2_inv (vec2* v){ v->x = -v->x; diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 0ec252e..ea0b039 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -313,7 +313,7 @@ void vkvg_close_path (VkvgContext ctx){ return; //prevent closing on the same point - if (vec2_equ(ctx->points[ctx->pointCount-1], + if (vec2d_equ(ctx->points[ctx->pointCount-1], ctx->points[ctx->pointCount - ctx->pathes[ctx->pathPtr]])) { if (ctx->pathes[ctx->pathPtr] < 4)//ensure enough points left for closing return; @@ -324,41 +324,41 @@ void vkvg_close_path (VkvgContext ctx){ _finish_path(ctx); } -void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy){ +void vkvg_rel_line_to (VkvgContext ctx, double dx, double dy){ if (ctx->status) return; if (_current_path_is_empty(ctx)){ ctx->status = VKVG_STATUS_NO_CURRENT_POINT; return; } - vec2 cp = _get_current_position(ctx); + vec2d cp = _get_current_position(ctx); vkvg_line_to(ctx, cp.x + dx, cp.y + dy); } -void vkvg_line_to (VkvgContext ctx, float x, float y) +void vkvg_line_to (VkvgContext ctx, double x, double y) { if (ctx->status) return; - vec2 p = {x,y}; + vec2d p = {x,y}; if (!_current_path_is_empty (ctx)){ //prevent adding the same point - if (vec2_equ (_get_current_position (ctx), p)) + if (vec2d_equ (_get_current_position (ctx), p)) return; } _add_point (ctx, x, y); } -void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2){ +void vkvg_arc (VkvgContext ctx, double xc, double yc, double radius, double a1, double a2){ if (ctx->status) return; while (a2 < a1)//positive arc must have a1 2.f * M_PIF) //limit arc to 2PI - a2 = a1 + 2.f * M_PIF; + if (a2 - a1 > M_2PI) //limit arc to 2PI + a2 = a1 + M_2PI; - vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc}; + vec2d v = {cos(a1)*radius + xc, sin(a1)*radius + yc}; - float step = _get_arc_step(ctx, radius); - float a = a1; + double step = _get_arc_step(ctx, radius); + double a = a1; if (_current_path_is_empty(ctx)){ _set_curve_start (ctx); @@ -370,7 +370,7 @@ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, floa a+=step; - if (EQUF(a2, a1)) + if (EQU(a2, a1)) return; while(a < a2){ @@ -380,31 +380,31 @@ void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, floa a+=step; } - if (EQUF(a2-a1,M_PIF*2.f)){//if arc is complete circle, last point is the same as the first one + if (EQU(a2-a1,M_2PI)){//if arc is complete circle, last point is the same as the first one _set_curve_end(ctx); vkvg_close_path(ctx); return; } a = a2; //vec2 lastP = v; - v.x = cosf(a)*radius + xc; - v.y = sinf(a)*radius + yc; + v.x = cos(a)*radius + xc; + v.y = sin(a)*radius + yc; //if (!vec2_equ (v,lastP))//this test should not be required _add_point (ctx, v.x, v.y); _set_curve_end(ctx); } -void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2) { +void vkvg_arc_negative (VkvgContext ctx, double xc, double yc, double radius, double a1, double a2) { if (ctx->status) return; while (a2 > a1) - a2 -= 2.f*M_PIF; - if (a1 - a2 > a1 + 2.f * M_PIF) //limit arc to 2PI - a2 = a1 - 2.f * M_PIF; + a2 -= M_2PI; + if (a1 - a2 > a1 + M_2PI) //limit arc to 2PI + a2 = a1 - M_2PI; - vec2 v = {cosf(a1)*radius + xc, sinf(a1)*radius + yc}; + vec2d v = {cos(a1)*radius + xc, sin(a1)*radius + yc}; - float step = _get_arc_step(ctx, radius); - float a = a1; + double step = _get_arc_step(ctx, radius); + double a = a1; if (_current_path_is_empty(ctx)){ _set_curve_start (ctx); @@ -416,28 +416,28 @@ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float a-=step; - if (EQUF(a2, a1)) + if (EQU(a2, a1)) return; while(a > a2){ - v.x = cosf(a)*radius + xc; - v.y = sinf(a)*radius + yc; + v.x = cos(a)*radius + xc; + v.y = sin(a)*radius + yc; _add_point (ctx,v.x,v.y); a-=step; } - if (EQUF(a1-a2,M_PIF*2.f))//if arc is complete circle, last point is the same as the first one + if (EQU(a1-a2,M_2PI))//if arc is complete circle, last point is the same as the first one return; a = a2; //vec2 lastP = v; - v.x = cosf(a)*radius + xc; - v.y = sinf(a)*radius + yc; + v.x = cos(a)*radius + xc; + v.y = sin(a)*radius + yc; //if (!vec2_equ (v,lastP)) _add_point (ctx, v.x, v.y); _set_curve_end(ctx); } -void vkvg_rel_move_to (VkvgContext ctx, float x, float y) +void vkvg_rel_move_to (VkvgContext ctx, double x, double y) { if (ctx->status) return; @@ -445,10 +445,10 @@ void vkvg_rel_move_to (VkvgContext ctx, float x, float y) ctx->status = VKVG_STATUS_NO_CURRENT_POINT; return; } - vec2 cp = _get_current_position(ctx); + vec2d cp = _get_current_position(ctx); vkvg_move_to(ctx, cp.x + x, cp.y + y); } -void vkvg_move_to (VkvgContext ctx, float x, float y) +void vkvg_move_to (VkvgContext ctx, double x, double y) { if (ctx->status) return; @@ -456,19 +456,19 @@ void vkvg_move_to (VkvgContext ctx, float x, float y) _add_point (ctx, x, y); } -void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) { +void vkvg_curve_to (VkvgContext ctx, double x1, double y1, double x2, double y2, double x3, double y3) { if (ctx->status) return; //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))) + if (EQU(x1,x2) && EQU(x2,x3) && EQU(y1,y2) && EQU(y2,y3)) { + if (_current_path_is_empty(ctx) || (EQU(_get_current_position(ctx).x,x1) && EQU(_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); + vec2d cp = _get_current_position(ctx); _recursive_bezier (ctx, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0); /*cp.x = x3; @@ -477,24 +477,24 @@ void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, flo _add_point(ctx,x3,y3); _set_curve_end (ctx); } -void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) { +void vkvg_rel_curve_to (VkvgContext ctx, double x1, double y1, double x2, double y2, double x3, double y3) { if (ctx->status) return; if (_current_path_is_empty(ctx)){ ctx->status = VKVG_STATUS_NO_CURRENT_POINT; return; } - vec2 cp = _get_current_position(ctx); + vec2d 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){ +void vkvg_fill_rectangle (VkvgContext ctx, double x, double y, double w, double h){ if (ctx->status) return; _vao_add_rectangle (ctx,x,y,w,h); //_record_draw_cmd(ctx); } -void vkvg_rectangle (VkvgContext ctx, float x, float y, float w, float h){ +void vkvg_rectangle (VkvgContext ctx, double x, double y, double w, double h){ if (ctx->status) return; _finish_path (ctx); @@ -624,25 +624,25 @@ void vkvg_fill_preserve (VkvgContext ctx){ _ensure_renderpass_is_started(ctx); _fill_ec(ctx); } -void _draw_stoke_cap (VkvgContext ctx, float hw, vec2 p0, vec2 n, bool isStart) { +void _draw_stoke_cap (VkvgContext ctx, double hw, vec2d p0, vec2d n, bool isStart) { Vertex v = {{0},ctx->curColor,{0,0,-1}}; VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); if (isStart){ - vec2 vhw = vec2_mult(n,hw); + vec2d vhw = vec2d_mult(n,hw); if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) - p0 = vec2_sub(p0, vhw); + p0 = vec2d_sub(p0, vhw); - vhw = vec2_perp(vhw); + vhw = vec2d_perp(vhw); if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ - float step = M_PIF / fmaxf(hw, 4.f); - float a = acosf(n.x) + M_PIF_2; + double step = M_PI / fmaxf(hw, 4.f); + double a = acosf(n.x) + M_PI_2; if (n.y < 0) - a = M_PIF-a; - float a1 = a + M_PIF; + a = M_PI-a; + double a1 = a + M_PI; a+=step; while (a < a1){ @@ -655,37 +655,37 @@ void _draw_stoke_cap (VkvgContext ctx, float hw, vec2 p0, vec2 n, bool isStart) firstIdx = p0Idx; } - v.pos = vec2_add(p0, vhw); + v.pos = vec2d_to_vec2(vec2d_add(p0, vhw)); _add_vertex(ctx, v); - v.pos = vec2_sub(p0, vhw); + v.pos = vec2d_to_vec2 (vec2d_sub(p0, vhw)); _add_vertex(ctx, v); _add_tri_indices_for_rect(ctx, firstIdx); }else{ - vec2 vhw = vec2_mult(n, hw); + vec2d vhw = vec2d_mult(n, hw); if (ctx->lineCap == VKVG_LINE_CAP_SQUARE) - p0 = vec2_add(p0, vhw); + p0 = vec2d_add(p0, vhw); - vhw = vec2_perp(vhw); + vhw = vec2d_perp(vhw); - v.pos = vec2_add(p0, vhw); + v.pos = vec2d_to_vec2 (vec2d_add(p0, vhw)); _add_vertex(ctx, v); - v.pos = vec2_sub(p0, vhw); + v.pos = vec2d_to_vec2 (vec2d_sub(p0, vhw)); _add_vertex(ctx, v); firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); if (ctx->lineCap == VKVG_LINE_CAP_ROUND){ - float step = M_PIF / fmaxf(hw, 4.f); - float a = acosf(n.x)+ M_PIF_2; + double step = M_PI / fmax(hw, 4.f); + double a = acos(n.x)+ M_PI_2; if (n.y < 0) - a = M_PIF-a; - float a1 = a - M_PIF; + a = M_PI-a; + double a1 = a - M_PI; a-=step; while ( a > a1){ - _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); + _add_vertexf(ctx, cos(a) * hw + p0.x, sin(a) * hw + p0.y); a-=step; } @@ -696,22 +696,22 @@ void _draw_stoke_cap (VkvgContext ctx, float hw, vec2 p0, vec2 n, bool isStart) } } -static bool dashOn = true; -static uint32_t curDash = 0; //current dash index -static float curDashOffset = 0.f; //cur dash offset between defined path point and last dash segment(on/off) start -static float totDashLength = 0; //total length of dashes -static vec2 normal = {0}; +static bool dashOn = true; +static uint32_t curDash = 0; //current dash index +static double curDashOffset = 0.0; //cur dash offset between defined path point and last dash segment(on/off) start +static double totDashLength = 0.0; //total length of dashes +static vec2d normal = {0}; -float _draw_dashed_segment (VkvgContext ctx, float hw, vec2 pL, vec2 p, vec2 pR, bool isCurve) { +float _draw_dashed_segment (VkvgContext ctx, double hw, vec2d pL, vec2d p, vec2d pR, bool isCurve) { if (!dashOn)//we test in fact the next dash start, if dashOn = true => next segment is a void. _build_vb_step (ctx, hw, pL, p, pR, isCurve); - vec2 d = vec2_sub (pR, p); - normal = vec2_norm (d); - float segmentLength = vec2_length(d); + vec2d d = vec2d_sub (pR, p); + normal = vec2d_norm (d); + double segmentLength = vec2d_length(d); while (curDashOffset < segmentLength){ - vec2 p0 = vec2_add (p, vec2_mult(normal, curDashOffset)); + vec2d p0 = vec2d_add (p, vec2d_mult(normal, curDashOffset)); _draw_stoke_cap (ctx, hw, p0, normal, dashOn); dashOn ^= true; @@ -720,11 +720,11 @@ float _draw_dashed_segment (VkvgContext ctx, float hw, vec2 pL, vec2 p, vec2 pR, curDash = 0; } curDashOffset -= segmentLength; - curDashOffset = fmodf(curDashOffset, totDashLength); + curDashOffset = fmod(curDashOffset, totDashLength); return segmentLength; } static uint32_t curPathPointIdx, lastPathPointIdx, ptrPath, iL, iR; -void _draw_segment (VkvgContext ctx, float hw, bool isCurve) { +void _draw_segment (VkvgContext ctx, double hw, bool isCurve) { iR = curPathPointIdx+1; if (ctx->dashCount > 0) _draw_dashed_segment(ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve); @@ -745,7 +745,7 @@ void vkvg_stroke_preserve (VkvgContext ctx) LOG(VKVG_LOG_INFO, "STROKE: ctx = %p; path ptr = %d;\n", ctx, ctx->pathPtr); curPathPointIdx = lastPathPointIdx = ptrPath = iL = iR = 0; - float hw = ctx->lineWidth / 2.0f; + double hw = ctx->lineWidth / 2.0f; while (ptrPath < ctx->pathPtr){ uint32_t ptrSegment = 0, lastSegmentPointIdx = 0; @@ -781,7 +781,7 @@ void vkvg_stroke_preserve (VkvgContext ctx) } else if (_path_is_closed(ctx,ptrPath)){ iL = lastPathPointIdx; }else{ - _draw_stoke_cap(ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx], ctx->points[curPathPointIdx+1]), true); + _draw_stoke_cap(ctx, hw, ctx->points[curPathPointIdx], vec2d_line_norm(ctx->points[curPathPointIdx], ctx->points[curPathPointIdx+1]), true); iL = curPathPointIdx++; } @@ -817,13 +817,13 @@ void vkvg_stroke_preserve (VkvgContext ctx) int32_t prevDash = (int32_t)curDash-1; if (prevDash < 0) curDash = ctx->dashCount-1; - float m = fminf (ctx->dashes[prevDash] - curDashOffset, ctx->dashes[curDash]); - vec2 p = vec2_sub(ctx->points[iR], vec2_mult(normal, m)); + double m = fmin (ctx->dashes[prevDash] - curDashOffset, ctx->dashes[curDash]); + vec2d p = vec2d_sub(ctx->points[iR], vec2d_mult(normal, m)); _draw_stoke_cap (ctx, hw, p, normal, false); } } else if (_path_is_closed(ctx,ptrPath)){ iR = firstPathPointIdx; - float cross = _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], false); + double 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]; VKVG_IBO_INDEX_TYPE ii = firstIdx; @@ -838,7 +838,7 @@ void vkvg_stroke_preserve (VkvgContext ctx) } curPathPointIdx++; }else - _draw_stoke_cap (ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx-1], ctx->points[curPathPointIdx]), false); + _draw_stoke_cap (ctx, hw, ctx->points[curPathPointIdx], vec2d_line_norm(ctx->points[curPathPointIdx-1], ctx->points[curPathPointIdx]), false); curPathPointIdx = firstPathPointIdx + pathPointCount; @@ -892,7 +892,7 @@ void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ _update_cur_pattern (ctx, pat); vkvg_pattern_reference (pat); } -void vkvg_set_line_width (VkvgContext ctx, float width){ +void vkvg_set_line_width (VkvgContext ctx, double width){ ctx->lineWidth = width; } void vkvg_set_line_cap (VkvgContext ctx, vkvg_line_cap_t cap){ @@ -925,7 +925,7 @@ vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx){ float vkvg_get_line_width (VkvgContext ctx){ return ctx->lineWidth; } -void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset){ +void vkvg_set_dash (VkvgContext ctx, const double* dashes, uint32_t num_dashes, double offset){ if (ctx->status) return; if (ctx->dashCount > 0) @@ -934,15 +934,15 @@ void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, f ctx->dashOffset = offset; if (ctx->dashCount == 0) return; - ctx->dashes = (float*)malloc (sizeof(float) * ctx->dashCount); - memcpy (ctx->dashes, dashes, sizeof(float) * ctx->dashCount); + ctx->dashes = (double*)malloc (sizeof(double) * ctx->dashCount); + memcpy (ctx->dashes, dashes, sizeof(double) * ctx->dashCount); } -void vkvg_get_dash (VkvgContext ctx, const float* dashes, uint32_t* num_dashes, float* offset){ +void vkvg_get_dash (VkvgContext ctx, const double* dashes, uint32_t* num_dashes, double* offset){ *num_dashes = ctx->dashCount; *offset = ctx->dashOffset; if (ctx->dashCount == 0 || dashes == NULL) return; - memcpy ((float*)dashes, ctx->dashes, sizeof(float) * ctx->dashCount); + memcpy ((double*)dashes, ctx->dashes, sizeof(double) * ctx->dashCount); } @@ -1109,8 +1109,8 @@ void vkvg_save (VkvgContext ctx){ sav->dashOffset = ctx->dashOffset; sav->dashCount = ctx->dashCount; if (ctx->dashCount > 0) { - sav->dashes = (float*)malloc (sizeof(float) * ctx->dashCount); - memcpy (sav->dashes, ctx->dashes, sizeof(float) * ctx->dashCount); + sav->dashes = (double*)malloc (sizeof(double) * ctx->dashCount); + memcpy (sav->dashes, ctx->dashes, sizeof(double) * ctx->dashCount); } sav->lineWidth = ctx->lineWidth; sav->curOperator= ctx->curOperator; @@ -1228,8 +1228,8 @@ void vkvg_restore (VkvgContext ctx){ free (ctx->dashes); ctx->dashCount = sav->dashCount; if (ctx->dashCount > 0) { - ctx->dashes = (float*)malloc (sizeof(float) * ctx->dashCount); - memcpy (ctx->dashes, sav->dashes, sizeof(float) * ctx->dashCount); + ctx->dashes = (double*)malloc (sizeof(double) * ctx->dashCount); + memcpy (ctx->dashes, sav->dashes, sizeof(double) * ctx->dashCount); } ctx->lineWidth = sav->lineWidth; diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 384805a..694b952 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -102,7 +102,7 @@ bool _current_path_is_empty (VkvgContext ctx) { return ctx->pathes [ctx->pathPtr] == 0; } //this function expect that current point exists -vec2 _get_current_position (VkvgContext ctx) { +vec2d _get_current_position (VkvgContext ctx) { return ctx->points[ctx->pointCount-1]; } //set curve start point and set path has curve bit @@ -190,11 +190,11 @@ void _resetMinMax (VkvgContext ctx) { ctx->xMin = ctx->yMin = FLT_MAX; ctx->xMax = ctx->yMax = FLT_MIN; } -void _add_point (VkvgContext ctx, float x, float y){ +void _add_point (VkvgContext ctx, double x, double y){ if (_check_point_array(ctx)) return; - ctx->points[ctx->pointCount] = (vec2){x,y}; + ctx->points[ctx->pointCount] = (vec2d){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) @@ -215,18 +215,18 @@ void _add_point (VkvgContext ctx, float x, float y){ if (y > ctx->yMax) ctx->yMax = y; } -float _normalizeAngle(float a) +float _normalizeAngle(double a) { - float res = ROUND_DOWN(fmodf(a,2.0f*M_PIF),100); - if (res < 0.0f) - return res + 2.0f*M_PIF; + float res = ROUND_DOWN(fmod(a,M_2PI),100); + if (res < 0.0) + return res + M_2PI; else return res; } -float _get_arc_step (VkvgContext ctx, float radius) { - float dx = 1, dy = 1; +float _get_arc_step (VkvgContext ctx, double radius) { + double dx = 1, dy = 1; vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy); - return M_PIF/sqrtf(radius)*0.35f/fmaxf(dx,dy); + return M_PI/sqrt(radius)*0.35/fmax(dx,dy); } void _create_gradient_buff (VkvgContext ctx){ vkvg_buffer_create (ctx->pSurf->dev, @@ -436,7 +436,7 @@ void _check_vao_size (VkvgContext ctx) { //if cmd is started buffers, are already bound, so no resize is possible //instead we flush, and clear vbo and ibo caches _flush_cmd_until_vx_base (ctx); - if (ctx->vertCount > ctx->sizeVBO) + if (ctx->vertCount > ctx->sizeVBO) _resize_vbo(ctx, ctx->sizeVertices); if (ctx->indCount > ctx->sizeIBO) _resize_ibo(ctx, ctx->sizeIndices); @@ -638,7 +638,7 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); vec4 srcRect = {{0},{0},{(float)surf->width},{(float)surf->height}}; - ctx->pushConsts.source = srcRect; + ctx->pushConsts.source = srcRect; break; } case VKVG_PATTERN_TYPE_LINEAR: @@ -733,54 +733,54 @@ void _init_descriptor_sets (VkvgContext ctx){ VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsGrad)); } //populate vertice buff for stroke -float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bool isCurve){ +float _build_vb_step (vkvg_context* ctx, double hw, vec2d pL, vec2d p0, vec2d pR, bool isCurve){ Vertex v = {{0},ctx->curColor, {0,0,-1}}; - vec2 v0 = vec2_sub(p0, pL); - vec2 v1 = vec2_sub(pR, p0); - float length_v0 = vec2_length(v0); - float length_v1 = vec2_length(v1); - if (length_v0 < FLT_EPSILON || length_v1 < FLT_EPSILON) - return 0; - vec2 v0n = vec2_div (v0, length_v0); - vec2 v1n = vec2_div (v1, length_v1); + vec2d v0 = vec2d_sub(p0, pL); + vec2d v1 = vec2d_sub(pR, p0); + double length_v0 = vec2d_length(v0); + double length_v1 = vec2d_length(v1); + if (length_v0 < DBL_EPSILON || length_v1 < DBL_EPSILON) + return 0; + vec2d v0n = vec2d_div (v0, length_v0); + vec2d v1n = vec2d_div (v1, length_v1); - vec2 bisec = vec2_norm(vec2_add(v0n,v1n)); + vec2d bisec = vec2d_norm(vec2d_add(v0n,v1n)); - float dot = v0n.x * v1n.x + v0n.y * v1n.y; - float alpha = acosf(dot)/2; - float cross = v0n.x * v1n.y - v0n.y * v1n.x; + double dot = v0n.x * v1n.x + v0n.y * v1n.y; + double alpha = acos(dot)/2; + double cross = v0n.x * v1n.y - v0n.y * v1n.x; if (cross<0) alpha = -alpha; - float lh = hw / cosf(alpha); - bisec = vec2_perp(bisec); + double lh = hw / cos(alpha); + bisec = vec2d_perp(bisec); - //limit bisectrice lenght, may be improved but ok for perf - lh=fminf (lh, fminf (sqrtf(length_v0*length_v0+hw*hw), sqrtf(length_v1*length_v1+hw*hw))); + //limit bisectrice lenght, may be improved but ok for perf + lh=fmin (lh, fmin (sqrt(length_v0*length_v0+hw*hw), sqrt(length_v1*length_v1+hw*hw))); - bisec = vec2_mult(bisec,lh); + bisec = vec2d_mult(bisec,lh); VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset); if (ctx->lineJoin == VKVG_LINE_JOIN_MITER || isCurve){ - v.pos = vec2_add(p0, bisec); + v.pos = vec2d_to_vec2(vec2d_add(p0, bisec)); _add_vertex(ctx, v); - v.pos = vec2_sub(p0, bisec); - _add_vertex(ctx, v); - _add_tri_indices_for_rect(ctx, idx); + v.pos = vec2d_to_vec2(vec2d_sub(p0, bisec)); + _add_vertex(ctx, v); + _add_tri_indices_for_rect(ctx, idx); }else{ - vec2 vp = vec2_perp(v0n); + vec2d vp = vec2d_perp(v0n); if (cross<0){ - v.pos = vec2_add (p0, bisec); + v.pos = vec2d_to_vec2(vec2d_add (p0, bisec)); _add_vertex(ctx, v); - v.pos = vec2_sub (p0, vec2_mult (vp, hw)); + v.pos = vec2d_to_vec2(vec2d_sub (p0, vec2d_mult (vp, hw))); }else{ - v.pos = vec2_add (p0, vec2_mult (vp, hw)); + v.pos = vec2d_to_vec2(vec2d_add (p0, vec2d_mult (vp, hw))); _add_vertex(ctx, v); - v.pos = vec2_sub (p0, bisec); - } + v.pos = vec2d_to_vec2(vec2d_sub (p0, bisec)); + } _add_vertex(ctx, v); if (ctx->lineJoin == VKVG_LINE_JOIN_BEVEL){ @@ -794,24 +794,24 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo _add_triangle_indices(ctx, idx+1, idx+3, idx+4); } }else if (ctx->lineJoin == VKVG_LINE_JOIN_ROUND){ - float step = M_PIF / hw; - float a = acosf(vp.x); + double step = M_PI / hw; + double a = acos(vp.x); if (vp.y < 0) a = -a; if (cross<0){ - a+=M_PIF; - float a1 = a + alpha*2; + a+=M_PI; + double a1 = a + alpha*2; a-=step; while (a > a1){ - _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); + _add_vertexf(ctx, cos(a) * hw + p0.x, sin(a) * hw + p0.y); a-=step; } }else{ - float a1 = a + alpha*2; + double a1 = a + alpha*2; a+=step; while (a < a1){ - _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y); + _add_vertexf(ctx, cos(a) * hw + p0.x, sin(a) * hw + p0.y); a+=step; } } @@ -831,11 +831,11 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo } - vp = vec2_mult (vec2_perp(v1n), hw); + vp = vec2d_mult (vec2d_perp(v1n), hw); if (cross<0) - v.pos = vec2_sub (p0, vp); + v.pos = vec2d_to_vec2(vec2d_sub (p0, vp)); else - v.pos = vec2_add (p0, vp); + v.pos = vec2d_to_vec2(vec2d_add (p0, vp)); _add_vertex(ctx, v); } @@ -855,14 +855,14 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo return cross; } -bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) { - float dX = p.x-p2.x; - float dY = p.y-p2.y; - float dX21 = p2.x-p1.x; - float dY12 = p1.y-p2.y; - float D = dY12*(p0.x-p2.x) + dX21*(p0.y-p2.y); - float s = dY12*dX + dX21*dY; - float t = (p2.y-p0.y)*dX + (p0.x-p2.x)*dY; +bool ptInTriangle(vec2d p, vec2d p0, vec2d p1, vec2d p2) { + double dX = p.x-p2.x; + double dY = p.y-p2.y; + double dX21 = p2.x-p1.x; + double dY12 = p1.y-p2.y; + double D = dY12*(p0.x-p2.x) + dX21*(p0.y-p2.y); + double s = dY12*dX + dX21*dY; + double t = (p2.y-p0.y)*dX + (p0.x-p2.x)*dY; if (D<0) return (s<=0) && (t<=0) && (s+t>=D); return (s>=0) && (t>=0) && (s+t<=D); @@ -886,8 +886,8 @@ void _free_ctx_save (vkvg_context_save_t* sav){ //no floating point arithmetic operation allowed in macro. #pragma warning(disable:4127) void _recursive_bezier (VkvgContext ctx, - float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4, + double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4, unsigned level) { if(level > CURVE_RECURSION_LIMIT) { @@ -896,36 +896,36 @@ void _recursive_bezier (VkvgContext ctx, // Calculate all the mid-points of the line segments //---------------------- - float x12 = (x1 + x2) / 2; - float y12 = (y1 + y2) / 2; - float x23 = (x2 + x3) / 2; - float y23 = (y2 + y3) / 2; - float x34 = (x3 + x4) / 2; - float y34 = (y3 + y4) / 2; - float x123 = (x12 + x23) / 2; - float y123 = (y12 + y23) / 2; - float x234 = (x23 + x34) / 2; - float y234 = (y23 + y34) / 2; - float x1234 = (x123 + x234) / 2; - float y1234 = (y123 + y234) / 2; + double x12 = (x1 + x2) / 2; + double y12 = (y1 + y2) / 2; + double x23 = (x2 + x3) / 2; + double y23 = (y2 + y3) / 2; + double x34 = (x3 + x4) / 2; + double y34 = (y3 + y4) / 2; + double x123 = (x12 + x23) / 2; + double y123 = (y12 + y23) / 2; + double x234 = (x23 + x34) / 2; + double y234 = (y23 + y34) / 2; + double x1234 = (x123 + x234) / 2; + double y1234 = (y123 + y234) / 2; if(level > 0) // Enforce subdivision first time { // Try to approximate the full cubic curve by a single straight line //------------------ - float dx = x4-x1; - float dy = y4-y1; + double dx = x4-x1; + double dy = y4-y1; - float d2 = fabsf(((x2 - x4) * dy - (y2 - y4) * dx)); - float d3 = fabsf(((x3 - x4) * dy - (y3 - y4) * dx)); + double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx)); + double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx)); - float da1, da2; + double da1, da2; if(d2 > CURVE_COLLINEARITY_EPSILON && d3 > CURVE_COLLINEARITY_EPSILON) { // Regular care //----------------- - if((d2 + d3)*(d2 + d3) <= (dx*dx + dy*dy) * (float)M_DISTANCE_TOLERANCE) + if((d2 + d3)*(d2 + d3) <= (dx*dx + dy*dy) * M_DISTANCE_TOLERANCE) { // If the curvature doesn't exceed the distance_tolerance value // we tend to finish subdivisions. @@ -937,13 +937,13 @@ void _recursive_bezier (VkvgContext ctx, // Angle & Cusp Condition //---------------------- - float a23 = atan2f(y3 - y2, x3 - x2); - da1 = fabsf(a23 - atan2f(y2 - y1, x2 - x1)); - da2 = fabsf(atan2f(y4 - y3, x4 - x3) - a23); - if(da1 >= M_PIF) da1 = M_2_PIF - da1; - if(da2 >= M_PIF) da2 = M_2_PIF - da2; + double a23 = atan2(y3 - y2, x3 - x2); + da1 = fabs(a23 - atan2(y2 - y1, x2 - x1)); + da2 = fabs(atan2(y4 - y3, x4 - x3) - a23); + if(da1 >= M_PI) da1 = M_2_PI - da1; + if(da2 >= M_PI) da2 = M_2_PI - da2; - if(da1 + da2 < (float)M_ANGLE_TOLERANCE) + if(da1 + da2 < M_ANGLE_TOLERANCE) { // Finally we can stop the recursion //---------------------- @@ -971,7 +971,7 @@ void _recursive_bezier (VkvgContext ctx, { // p1,p3,p4 are collinear, p2 is considerable //---------------------- - if(d2 * d2 <= (float)M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) + if(d2 * d2 <= M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) { if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) { @@ -981,8 +981,8 @@ void _recursive_bezier (VkvgContext ctx, // Angle Condition //---------------------- - da1 = fabsf(atan2f(y3 - y2, x3 - x2) - atan2f(y2 - y1, x2 - x1)); - if(da1 >= M_PIF) da1 = M_2_PIF - da1; + da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); + if(da1 >= M_PI) da1 = M_2_PI - da1; if(da1 < M_ANGLE_TOLERANCE) { @@ -1003,7 +1003,7 @@ void _recursive_bezier (VkvgContext ctx, } else if(d3 > CURVE_COLLINEARITY_EPSILON) { // p1,p2,p4 are collinear, p3 is considerable //---------------------- - if(d3 * d3 <= (float)M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) + if(d3 * d3 <= M_DISTANCE_TOLERANCE * (dx*dx + dy*dy)) { if(M_ANGLE_TOLERANCE < CURVE_ANGLE_TOLERANCE_EPSILON) { @@ -1013,8 +1013,8 @@ void _recursive_bezier (VkvgContext ctx, // Angle Condition //---------------------- - da1 = fabsf(atan2f(y4 - y3, x4 - x3) - atan2f(y3 - y2, x3 - x2)); - if(da1 >= M_PIF) da1 = M_2_PIF - da1; + da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2)); + if(da1 >= M_PI) da1 = M_2_PI - da1; if(da1 < M_ANGLE_TOLERANCE) { @@ -1039,7 +1039,7 @@ void _recursive_bezier (VkvgContext ctx, //----------------- dx = x1234 - (x1 + x4) / 2; dy = y1234 - (y1 + y4) / 2; - if(dx*dx + dy*dy <= (float)M_DISTANCE_TOLERANCE) + if(dx*dx + dy*dy <= M_DISTANCE_TOLERANCE) { _add_point (ctx, x1234, y1234); return; @@ -1092,7 +1092,7 @@ void _poly_fill (VkvgContext ctx){ 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]; + v.pos = vec2d_to_vec2(ctx->points [i+firstPtIdx]); ctx->vertexCache[ctx->vertCount++] = v; _check_vertex_cache_size(ctx); } @@ -1123,7 +1123,7 @@ void _fill_ec (VkvgContext ctx){ while (ptrPath < ctx->pathPtr){ ctx->pathes[ptrPath] |= PATH_CLOSED_BIT;//close path - uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK; + 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)); @@ -1131,16 +1131,16 @@ void _fill_ec (VkvgContext ctx){ VKVG_IBO_INDEX_TYPE i = 0; //init points link list - while (i < pathPointCount-1){ - v.pos = ctx->points[i+firstPtIdx]; - ear_clip_point ecp = {v.pos, firstVertIdx+i, &ecps[i+1]}; + while (i < pathPointCount-1){ + ear_clip_point ecp = {ctx->points[i+firstPtIdx], firstVertIdx+i, &ecps[i+1]}; + v.pos = vec2d_to_vec2(ecp.pos); ecps[i] = ecp; _add_vertex(ctx, v); i++; } - v.pos = ctx->points[i+firstPtIdx]; - ear_clip_point ecp = {v.pos, firstVertIdx+i, ecps}; + ear_clip_point ecp = {ctx->points[i+firstPtIdx], firstVertIdx+i, ecps}; + v.pos = vec2d_to_vec2(ecp.pos); ecps[i] = ecp; _add_vertex(ctx, v); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 592bc1f..b87d0c5 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -76,10 +76,10 @@ typedef struct { typedef struct _vkvg_context_save_t{ struct _vkvg_context_save_t* pNext; - float lineWidth; + double lineWidth; uint32_t dashCount; //value count in dash array, 0 if dash not set. - float dashOffset; //an offset for dash - float* dashes; //an array of alternate lengths of on and off stroke. + double dashOffset; //an offset for dash + double* dashes; //an array of alternate lengths of on and off stroke. vkvg_operator_t curOperator; @@ -120,10 +120,10 @@ typedef struct _vkvg_context_t { uint32_t curColor; - float xMin; - float xMax; - float yMin; - float yMax; + double xMin; + double xMax; + double yMin; + double yMax; vkvg_buff uboGrad; //uniform buff obj holdings gradient infos @@ -145,7 +145,7 @@ typedef struct _vkvg_context_t { VKVG_IBO_INDEX_TYPE* indexCache; //pathes, exists until stroke of fill - vec2* points; //points array + vec2d* points; //points array uint32_t sizePoints; //reserved size uint32_t pointCount; //effective points count @@ -156,10 +156,10 @@ typedef struct _vkvg_context_t { uint32_t segmentPtr; //current segment count in current path having curves - float lineWidth; + double lineWidth; uint32_t dashCount; //value count in dash array, 0 if dash not set. - float dashOffset; //an offset for dash - float* dashes; //an array of alternate lengths of on and off stroke. + double dashOffset; //an offset for dash + double* dashes; //an array of alternate lengths of on and off stroke. vkvg_operator_t curOperator; vkvg_line_cap_t lineCap; @@ -186,7 +186,7 @@ typedef struct _vkvg_context_t { }vkvg_context; typedef struct _ear_clip_point{ - vec2 pos; + vec2d pos; VKVG_IBO_INDEX_TYPE idx; struct _ear_clip_point* next; }ear_clip_point; @@ -205,11 +205,11 @@ void _set_curve_start (VkvgContext ctx); void _set_curve_end (VkvgContext ctx); bool _path_has_curves (VkvgContext ctx, uint32_t ptrPath); -float _normalizeAngle (float a); -float _get_arc_step (VkvgContext ctx, float radius); +float _normalizeAngle (double a); +float _get_arc_step (VkvgContext ctx, double radius); -vec2 _get_current_position (VkvgContext ctx); -void _add_point (VkvgContext ctx, float x, float y); +vec2d _get_current_position(VkvgContext ctx); +void _add_point (VkvgContext ctx, double x, double y); void _resetMinMax (VkvgContext ctx); @@ -224,7 +224,7 @@ void _add_vertexf (VkvgContext ctx, float x, float y); void _set_vertex (VkvgContext ctx, uint32_t idx, Vertex v); void _add_triangle_indices (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i0, VKVG_IBO_INDEX_TYPE i1, VKVG_IBO_INDEX_TYPE i2); void _add_tri_indices_for_rect (VkvgContext ctx, VKVG_IBO_INDEX_TYPE i); -float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bool isCurve); +float _build_vb_step (vkvg_context* ctx, double hw, vec2d pL, vec2d p0, vec2d pR, bool isCurve); void _vao_add_rectangle (VkvgContext ctx, float x, float y, float width, float height); void _bind_draw_pipeline (VkvgContext ctx); @@ -251,12 +251,15 @@ void _free_ctx_save (vkvg_context_save_t* sav); static inline float vec2_zcross (vec2 v1, vec2 v2){ return v1.x*v2.y-v1.y*v2.x; } -static inline float ecp_zcross (ear_clip_point* p0, ear_clip_point* p1, ear_clip_point* p2){ - return vec2_zcross (vec2_sub (p1->pos, p0->pos), vec2_sub (p2->pos, p0->pos)); +static inline double vec2d_zcross (vec2d v1, vec2d v2){ + return v1.x*v2.y-v1.y*v2.x; +} +static inline double ecp_zcross (ear_clip_point* p0, ear_clip_point* p1, ear_clip_point* p2){ + return vec2d_zcross (vec2d_sub (p1->pos, p0->pos), vec2d_sub (p2->pos, p0->pos)); } void _recursive_bezier(VkvgContext ctx, - float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4, + double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4, unsigned level); void _bezier (VkvgContext ctx, float x1, float y1, float x2, float y2, diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 96fed15..dead525 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -530,7 +530,7 @@ void _show_text_run (VkvgContext ctx, VkvgText tr) { hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos (tr->hbBuf, &glyph_count); Vertex v = {{0},ctx->curColor,{0,0,-1}}; - vec2 pen = {0,0}; + vec2d pen = {0,0}; if (!_current_path_is_empty(ctx)) pen = _get_current_position(ctx); diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index f49e389..8621663 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -38,8 +38,16 @@ #define M_PIF 3.14159265358979323846f /* float pi */ #define M_PIF_2 1.57079632679489661923f #define M_2_PIF 0.63661977236758134308f // 2/pi -/*#ifndef M_2_PI - #define M_2_PI 0.63661977236758134308 // 2/pi +#ifndef M_PI + #define M_PI 3.14159265358979323846 /* pi */ + #define M_2PI 6.28318530717958647692 /* 2 * pi */ + #define M_PI_2 1.57079632679489661923 /* pi/2 */ + #define M_PI_4 0.78539816339744830962 /* pi/4 */ + #define M_1_PI 0.31830988618379067154 /* 1/pi */ + #define M_2_PI 0.63661977236758134308 /* 2/pi */ + #define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ + #define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ + #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ #endif*/ #ifdef DEBUG @@ -55,8 +63,10 @@ #define PATH_ELT_MASK 0x3FFFFFFF /* Bit mask for fetching path element value */ #define ROUNDF(f, c) (((float)((int)((f) * (c))) / (c))) -#define ROUND_DOWN(v,p) (floorf(v * p) / p) +#define ROUND_DOWNF(v,p) (floorf(v * p) / p) +#define ROUND_DOWN(v,p) (floor(v * p) / p) #define EQUF(a, b) (fabsf(a-b)<=FLT_EPSILON) +#define EQU(a, b) (fabs(a-b)<=DBL_EPSILON) #include "cross_os.h" diff --git a/src/vkvg_matrix.c b/src/vkvg_matrix.c index 6094efc..161f336 100644 --- a/src/vkvg_matrix.c +++ b/src/vkvg_matrix.c @@ -240,9 +240,9 @@ void vkvg_matrix_multiply (vkvg_matrix_t *result, const vkvg_matrix_t *a, const *result = r; } -void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, float *dy) +void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, double *dx, double *dy) { - float new_x, new_y; + double new_x, new_y; new_x = (matrix->xx * *dx + matrix->xy * *dy); new_y = (matrix->yx * *dx + matrix->yy * *dy); @@ -250,7 +250,7 @@ void vkvg_matrix_transform_distance (const vkvg_matrix_t *matrix, float *dx, flo *dx = new_x; *dy = new_y; } -void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *y) +void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, double *x, double *y) { vkvg_matrix_transform_distance (matrix, x, y); diff --git a/tests/common/rnd.c b/tests/common/rnd.c index 6fd3895..5e637b4 100644 --- a/tests/common/rnd.c +++ b/tests/common/rnd.c @@ -1,6 +1,6 @@ static int _rnd_count = 10000; static int _cur_rnd = 0; -static float _rnd[] = { 0.39540747, +static double _rnd[] = { 0.39540747, 0.841546, 0.52073574, 0.80399257, 0.95868486, 0.46164507, 0.5644759, 0.50258803, 0.1953517, 0.40522006, 0.7953865, 0.7795385, 0.6009604, 0.03921096, 0.56872225, 0.93369347, 0.7019503, 0.5392296, 0.2671585, 0.87286836, 0.28110227, 0.41505373, 0.8609184, 0.65234584, 0.18079561, 0.1345461, 0.26905555, 0.97823226, 0.9349287, 0.37662244, 0.47883937, @@ -1002,11 +1002,11 @@ static float _rnd[] = { 0.39540747, 0.14544618, 0.5170238, 0.67768705, 0.23049083, 0.4064205, 0.09570609, 0.9652428, 0.028672969, 0.1510829, 0.30246252, 0.4205718, 0.2910258, 0.67623764, 0.69533557, 0.33236894, 0.17955771, 0.25711736, 0.5261945, 0.48835787}; -float rndf() { +double rndf() { if (_cur_rnd > _rnd_count) _cur_rnd = 0; return _rnd[_cur_rnd++]; } -float rndf_reset() { +double rndf_reset() { _cur_rnd = 0; -} \ No newline at end of file +} diff --git a/tests/common/rnd.h b/tests/common/rnd.h index b04c2e8..051c2f4 100644 --- a/tests/common/rnd.h +++ b/tests/common/rnd.h @@ -1,2 +1,2 @@ -float rndf(); -float rndf_reset(); \ No newline at end of file +double rndf(); +double rndf_reset(); diff --git a/tests/common/test.c b/tests/common/test.c index 24ddad9..ce4babc 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -616,11 +616,11 @@ void randomize_color(VkvgContext ctx) { rndf() ); } -void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact) { - float w = (float)test_width; - float h = (float)test_height; +void draw_random_shape (VkvgContext ctx, shape_t shape, double sizeFact) { + double w = (double)test_width; + double h = (double)test_height; - float x, y, z, v, r; + double x, y, z, v, r; randomize_color (ctx); @@ -654,13 +654,13 @@ void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact) { r = MIN(v / 2, z / 2); vkvg_move_to(ctx, x, y + r); - vkvg_arc(ctx, x + r, y + r, r, (float)M_PI, (float)-M_PI_2); + vkvg_arc(ctx, x + r, y + r, r, M_PI, -M_PI_2); vkvg_line_to(ctx, x + z - r, y); - vkvg_arc(ctx, x + z - r, y + r, r, (float)-M_PI_2, 0); + vkvg_arc(ctx, x + z - r, y + r, r, -M_PI_2, 0); vkvg_line_to(ctx, x + z, y + v - r); - vkvg_arc(ctx, x + z - r, y + v - r, r, 0, (float)M_PI_2); + vkvg_arc(ctx, x + z - r, y + v - r, r, 0, M_PI_2); vkvg_line_to(ctx, x + r, y + v); - vkvg_arc(ctx, x + r, y + v - r, r, (float)M_PI_2, (float)M_PI); + vkvg_arc(ctx, x + r, y + v - r, r, M_PI_2, M_PI); vkvg_line_to(ctx, x, y + r); vkvg_close_path(ctx); break; @@ -671,19 +671,19 @@ void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact) { x = rndf() * w; y = rndf() * h; - r = truncf((sizeFact*MIN(w,h)*rndf())+1.f); + r = trunc((sizeFact*MIN(w,h)*rndf())+1.0); /*float r = 0.5f*w*rand()/RAND_MAX; float x = truncf(0.5f * w*rand()/RAND_MAX + r); float y = truncf(0.5f * w*rand()/RAND_MAX + r);*/ - vkvg_arc(ctx, x, y, r, 0, (float)M_PI * 2.0f); + vkvg_arc(ctx, x, y, r, 0, M_PI * 2.0); break; case SHAPE_TRIANGLE: case SHAPE_STAR: x = rndf() * w; y = rndf() * h; - z = rndf() * sizeFact + 0.15f; //scale + z = rndf() * sizeFact + 0.15; //scale vkvg_move_to (ctx, x+star_points[0][0]*z, y+star_points[0][1]*z); for (int s=1; s<11; s++) @@ -696,15 +696,15 @@ void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact) { } } void draw_random_curve (VkvgContext ctx) { - float w = (float)test_width; - float h = (float)test_height; - - float x2 = w*rndf(); - float y2 = h*rndf(); - float cp_x1 = w*rndf(); - float cp_y1 = h*rndf(); - float cp_x2 = w*rndf(); - float cp_y2 = h*rndf(); + double w = (double)test_width; + double h = (double)test_height; + + double x2 = w*rndf(); + double y2 = h*rndf(); + double cp_x1 = w*rndf(); + double cp_y1 = h*rndf(); + double cp_x2 = w*rndf(); + double cp_y2 = h*rndf(); vkvg_curve_to(ctx, cp_x1, cp_y1, cp_x2, cp_y2, x2, y2); } diff --git a/tests/common/test.h b/tests/common/test.h index 58fe95f..affd1c2 100644 --- a/tests/common/test.h +++ b/tests/common/test.h @@ -108,7 +108,7 @@ void perform_test (void(*testfunc)(), const char* testName, int argc, char *argv void perform_test_offscreen (void(*testfunc)(void), const char *testName, int argc, char* argv[]); void randomize_color (VkvgContext ctx); -void draw_random_shape (VkvgContext ctx, shape_t shape, float sizeFact); +void draw_random_shape (VkvgContext ctx, shape_t shape, double sizeFact); void draw_random_curve (VkvgContext ctx); //run test in 3 step: init, run, clear. diff --git a/tests/random_rects.c b/tests/random_rects.c index f192206..5eede5c 100644 --- a/tests/random_rects.c +++ b/tests/random_rects.c @@ -12,7 +12,7 @@ vkvg_rectangle(ctx, x, y, z, v); }*/ -static float shape_size = 0.2f; +static double shape_size = 0.2; void _shape_fill(shape_t shape){ VkvgContext ctx = _initCtx ();