* @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
*
* @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
*
* @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.
*
* @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.
*
* @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.
*
* @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.
*
* @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.
*
* @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.
*
* @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.
*
* @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
*
* @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
*
* @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
*
* @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.
*
* @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
};
}vec2;
-typedef struct {
- double x;
- double y;
+typedef union {
+ __m128d raw;// __attribute__ ((vector_size (16)));
+ struct {
+ double x;
+ double y;
+ };
}vec2d;
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);
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){
}
// 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){
}
// 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;
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;
_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<a2
- a2 += 2.f*M_PIF;
+ a2 += M_2PI;
- if (a2 - 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);
a+=step;
- if (EQUF(a2, a1))
+ if (EQU(a2, a1))
return;
while(a < a2){
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);
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;
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;
_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;
_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);
_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){
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;
}
}
}
-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;
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);
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;
} 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++;
}
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;
}
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;
_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){
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)
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);
}
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;
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;
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
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)
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,
//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);
_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:
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){
_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;
}
}
}
- 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);
}
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);
//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)
{
// 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.
// 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
//----------------------
{
// 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)
{
// 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)
{
} 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)
{
// 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)
{
//-----------------
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;
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);
}
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));
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);
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;
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
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
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;
}vkvg_context;
typedef struct _ear_clip_point{
- vec2 pos;
+ vec2d pos;
VKVG_IBO_INDEX_TYPE idx;
struct _ear_clip_point* next;
}ear_clip_point;
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);
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);
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,
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);
#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
#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"
*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);
*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);
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,
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
+}
-float rndf();
-float rndf_reset();
\ No newline at end of file
+double rndf();
+double rndf_reset();
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);
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;
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++)
}
}
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);
}
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.
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 ();