summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-04-29 03:54:29 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-07-16 14:22:37 +0200
commit8c6d3a47e08c9f1330d2316eaa708ff097d02d2a (patch)
tree370aded9143a7b182dcbdc490e9df362d4c91095
parent6ba0aa0111253b1b5fdea4d3e9e364ee994fd1da (diff)
add curve debug facility, measure frame rateCurvesDebug
-rw-r--r--CMakeLists.txt43
-rw-r--r--logo.pngbin0 -> 11252 bytes
-rw-r--r--src/vkvg_context.c12
-rw-r--r--src/vkvg_context_internal.c51
-rw-r--r--src/vkvg_context_internal.h10
-rw-r--r--tests/cairo-tests.h11
-rw-r--r--tests/common/vkengine.c (renamed from tests/vkengine.c)0
-rw-r--r--tests/common/vkengine.h (renamed from tests/vkengine.h)0
-rw-r--r--tests/perf-test.h172
-rw-r--r--tests/perf_test_0.c147
-rw-r--r--tests/test_curves.c1243
11 files changed, 1648 insertions, 41 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e7a29e2..99cae96 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug")
ENDIF()
OPTION(VKVG_BUILD_TESTS "build tests with glfw" ON)
+SET(CAIRO_INCLUDE_DIRECTORY "/usr/include/cairo" CACHE STRING "CAIRO include directory")
set(VULKAN_SDK "$ENV{VULKAN_SDK}" CACHE STRING "LunarG Vulkan SDK path")
if (VULKAN_SDK)
@@ -140,20 +141,30 @@ INSTALL(TARGETS vkvg
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
-if (GLFW3_FOUND)
- #build test app
- ADD_EXECUTABLE(${PROJECT_NAME}_test tests/test1.c tests/vkengine.c)
- TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}_test PRIVATE
- ${Vulkan_INCLUDE_DIRS}
- ${CMAKE_CURRENT_SOURCE_DIR}/include
- ${CMAKE_CURRENT_SOURCE_DIR}/src
- ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include
- ${CMAKE_CURRENT_SOURCE_DIR}/vkh/src
- )
- TARGET_LINK_LIBRARIES(${PROJECT_NAME}_test
- ${Vulkan_LIBRARIES}
- ${GLFW3_LIBRARY}
- vkh_static
- vkvg
- )
+if (GLFW3_FOUND AND VKVG_BUILD_TESTS)
+ #build test apps
+ FILE(GLOB TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} tests/*.c)
+ FOREACH(TEST_FILE ${TESTS})
+ GET_FILENAME_COMPONENT(TEST_NAME ${TEST_FILE} NAME_WE)
+ ADD_EXECUTABLE(${PROJECT_NAME}_${TEST_NAME} ${TEST_FILE} tests/common/vkengine.c)
+ TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}_${TEST_NAME} PRIVATE
+ ${CAIRO_INCLUDE_DIRECTORY}
+ ${Vulkan_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/tests/common/
+ ${CMAKE_CURRENT_SOURCE_DIR}/vkh/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/vkh/src
+
+ ${FREETYPE_INCLUDE_DIRS}
+ ${HARFBUZZ_INCLUDE_DIRS}
+ ${FONTCONFIG_INCLUDE_DIR}
+ )
+ TARGET_LINK_LIBRARIES(${PROJECT_NAME}_${TEST_NAME}
+ ${Vulkan_LIBRARIES}
+ ${GLFW3_LIBRARY}
+ vkh_static
+ vkvg
+ )
+ ENDFOREACH()
endif ()
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000..84fd6f6
--- /dev/null
+++ b/logo.png
Binary files differ
diff --git a/src/vkvg_context.c b/src/vkvg_context.c
index 99ebcf9..6bdf6ed 100644
--- a/src/vkvg_context.c
+++ b/src/vkvg_context.c
@@ -31,6 +31,16 @@ static vec2 debugLinePoints[1000];
static uint32_t dlpCount = 0;
#endif
+void _init_debug_curves (VkvgContext ctx) {
+ ctx->m_approximation_scale = 1.0;
+ ctx->m_angle_tolerance = 0.05;
+ ctx->m_distance_tolerance = 0.1;
+ ctx->m_cusp_limit = 0.25;
+ ctx->curve_recursion_limit = 16;
+ ctx->curve_collinearity_epsilon = 0.001;
+ ctx->curve_angle_tolerance_epsilon = 0.1;
+}
+
VkvgContext vkvg_create(VkvgSurface surf)
{
LOG(LOG_INFO, "CREATE Context: surf = %lu\n", surf);
@@ -89,6 +99,8 @@ VkvgContext vkvg_create(VkvgSurface surf)
ctx->references = 1;
+ _init_debug_curves (ctx);
+
return ctx;
}
void vkvg_flush (VkvgContext ctx){
diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c
index 18ba758..b3ca6de 100644
--- a/src/vkvg_context_internal.c
+++ b/src/vkvg_context_internal.c
@@ -187,7 +187,7 @@ void _record_draw_cmd (VkvgContext ctx){
//DEBUG
/*vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired);
vkCmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, 0, 1);
- vkCmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);*/
+ _bind_draw_pipeline(ctx);*/
//////////
ctx->curIndStart = ctx->indCount;
@@ -522,6 +522,9 @@ void _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32_
vec2 v0n = vec2_line_norm(ctx->points[iL], ctx->points[i]);
vec2 v1n = vec2_line_norm(ctx->points[i], ctx->points[iR]);
+ if (vec2_equ(v0n,v1n))
+ return;
+
vec2 bisec = vec2_norm(vec2_add(v0n,v1n));
float alpha = acos(v0n.x * v1n.x + v0n.y * v1n.y)/2;
@@ -635,7 +638,7 @@ void _free_ctx_save (vkvg_context_save_t* sav){
free (sav);
}
-
+/*
#define m_approximation_scale 1.0
#define m_angle_tolerance 0.01
#define m_distance_tolerance 1.0
@@ -643,12 +646,12 @@ void _free_ctx_save (vkvg_context_save_t* sav){
#define curve_recursion_limit 10
#define curve_collinearity_epsilon 1.7
#define curve_angle_tolerance_epsilon 0.001
-
+*/
void _recursive_bezier (VkvgContext ctx,
float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
unsigned level) {
- if(level > curve_recursion_limit)
+ if(level > ctx->curve_recursion_limit)
{
return;
}
@@ -680,16 +683,16 @@ void _recursive_bezier (VkvgContext ctx,
float da1, da2;
- if(d2 > curve_collinearity_epsilon && d3 > curve_collinearity_epsilon)
+ if(d2 > ctx->curve_collinearity_epsilon && d3 > ctx->curve_collinearity_epsilon)
{
// Regular care
//-----------------
- if((d2 + d3)*(d2 + d3) <= m_distance_tolerance * (dx*dx + dy*dy))
+ if((d2 + d3)*(d2 + d3) <= ctx->m_distance_tolerance * (dx*dx + dy*dy))
{
// If the curvature doesn't exceed the distance_tolerance value
// we tend to finish subdivisions.
//----------------------
- if(m_angle_tolerance < curve_angle_tolerance_epsilon)
+ if(ctx->m_angle_tolerance < ctx->curve_angle_tolerance_epsilon)
{
_add_point (ctx, x1234, y1234);
return;
@@ -703,7 +706,7 @@ void _recursive_bezier (VkvgContext ctx,
if(da1 >= M_PI) da1 = M_2_PI - da1;
if(da2 >= M_PI) da2 = M_2_PI - da2;
- if(da1 + da2 < m_angle_tolerance)
+ if(da1 + da2 < ctx->m_angle_tolerance)
{
// Finally we can stop the recursion
//----------------------
@@ -711,15 +714,15 @@ void _recursive_bezier (VkvgContext ctx,
return;
}
- if(m_cusp_limit != 0.0)
+ if(ctx->m_cusp_limit != 0.0)
{
- if(da1 > m_cusp_limit)
+ if(da1 > ctx->m_cusp_limit)
{
_add_point (ctx, x2, y2);
return;
}
- if(da2 > m_cusp_limit)
+ if(da2 > ctx->m_cusp_limit)
{
_add_point (ctx, x3, y3);
return;
@@ -727,13 +730,13 @@ void _recursive_bezier (VkvgContext ctx,
}
}
} else {
- if(d2 > curve_collinearity_epsilon)
+ if(d2 > ctx->curve_collinearity_epsilon)
{
// p1,p3,p4 are collinear, p2 is considerable
//----------------------
- if(d2 * d2 <= m_distance_tolerance * (dx*dx + dy*dy))
+ if(d2 * d2 <= ctx->m_distance_tolerance * (dx*dx + dy*dy))
{
- if(m_angle_tolerance < curve_angle_tolerance_epsilon)
+ if(ctx->m_angle_tolerance < ctx->curve_angle_tolerance_epsilon)
{
_add_point (ctx, x1234, y1234);
return;
@@ -744,28 +747,28 @@ void _recursive_bezier (VkvgContext ctx,
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)
+ if(da1 < ctx->m_angle_tolerance)
{
_add_point (ctx, x2, y2);
_add_point (ctx, x3, y3);
return;
}
- if(m_cusp_limit != 0.0)
+ if(ctx->m_cusp_limit != 0.0)
{
- if(da1 > m_cusp_limit)
+ if(da1 > ctx->m_cusp_limit)
{
_add_point (ctx, x2, y2);
return;
}
}
}
- } else if(d3 > curve_collinearity_epsilon) {
+ } else if(d3 > ctx->curve_collinearity_epsilon) {
// p1,p2,p4 are collinear, p3 is considerable
//----------------------
- if(d3 * d3 <= m_distance_tolerance * (dx*dx + dy*dy))
+ if(d3 * d3 <= ctx->m_distance_tolerance * (dx*dx + dy*dy))
{
- if(m_angle_tolerance < curve_angle_tolerance_epsilon)
+ if(ctx->m_angle_tolerance < ctx->curve_angle_tolerance_epsilon)
{
_add_point (ctx, x1234, y1234);
return;
@@ -776,16 +779,16 @@ void _recursive_bezier (VkvgContext ctx,
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)
+ if(da1 < ctx->m_angle_tolerance)
{
_add_point (ctx, x2, y2);
_add_point (ctx, x3, y3);
return;
}
- if(m_cusp_limit != 0.0)
+ if(ctx->m_cusp_limit != 0.0)
{
- if(da1 > m_cusp_limit)
+ if(da1 > ctx->m_cusp_limit)
{
_add_point (ctx, x3, y3);
return;
@@ -799,7 +802,7 @@ void _recursive_bezier (VkvgContext ctx,
//-----------------
dx = x1234 - (x1 + x4) / 2;
dy = y1234 - (y1 + y4) / 2;
- if(dx*dx + dy*dy <= m_distance_tolerance)
+ if(dx*dx + dy*dy <= ctx->m_distance_tolerance)
{
_add_point (ctx, x1234, y1234);
return;
diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h
index e0282d7..0ab0e42 100644
--- a/src/vkvg_context_internal.h
+++ b/src/vkvg_context_internal.h
@@ -28,7 +28,7 @@
#include "vkh.h"
#include "vkvg_fonts.h"
-#define VKVG_PTS_SIZE 16384
+#define VKVG_PTS_SIZE 32768
#define VKVG_VBO_SIZE VKVG_PTS_SIZE * 2
#define VKVG_IBO_SIZE VKVG_VBO_SIZE * 2
#define VKVG_PATHES_SIZE 256
@@ -137,6 +137,14 @@ typedef struct _vkvg_context_t {
vkvg_context_save_t* pSavedCtxs;//last ctx saved ptr
VkClearRect clearRect;
+ //debug curves
+ float m_approximation_scale;
+ float m_angle_tolerance;
+ float m_distance_tolerance;
+ float m_cusp_limit;
+ float curve_recursion_limit;
+ float curve_collinearity_epsilon;
+ float curve_angle_tolerance_epsilon;
}vkvg_context;
bool _current_path_is_empty (VkvgContext ctx);
diff --git a/tests/cairo-tests.h b/tests/cairo-tests.h
new file mode 100644
index 0000000..67fdb98
--- /dev/null
+++ b/tests/cairo-tests.h
@@ -0,0 +1,11 @@
+#ifndef CAIROTESTS_H
+#define CAIROTESTS_H
+
+#include "cairo.h"
+
+void* createContext() {
+
+ cairo_create();
+}
+
+#endif // CAIROTESTS_H
diff --git a/tests/vkengine.c b/tests/common/vkengine.c
index e4f04fb..e4f04fb 100644
--- a/tests/vkengine.c
+++ b/tests/common/vkengine.c
diff --git a/tests/vkengine.h b/tests/common/vkengine.h
index 1bf33a8..1bf33a8 100644
--- a/tests/vkengine.h
+++ b/tests/common/vkengine.h
diff --git a/tests/perf-test.h b/tests/perf-test.h
new file mode 100644
index 0000000..3df035d
--- /dev/null
+++ b/tests/perf-test.h
@@ -0,0 +1,172 @@
+#ifndef PERFTEST_H
+#define PERFTEST_H
+
+#include "vkvg.h"
+#include <stdlib.h>
+#include <float.h>
+
+enum DrawMode {
+ DM_FILL = 0x1,
+ DM_STROKE = 0x2,
+ DM_BOTH = 0x3
+};
+
+typedef struct _results {
+ double run_min;
+ double run_max;
+ double avg_time;
+ double median_time;
+ double std_deriv;
+} results_t;
+
+results_t initResults () {
+ results_t res = {};
+ res.run_min = DBL_MAX;
+ res.run_max = DBL_MIN;
+ return res;
+}
+
+typedef struct _options {
+ char* test_name;
+ int iterations;
+ int count;
+ int width;
+ int height;
+ enum DrawMode drawMode;
+} options_t;
+
+options_t initOptions (int argc, char *argv[]) {
+ options_t opt = {};
+ opt.iterations = 100;
+ opt.count = 1000;
+ opt.width = 1024;
+ opt.height = 800;
+ opt.drawMode = DM_FILL;
+
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 'w':
+ sscanf (argv[++i], "%d", &opt.width);
+ break;
+ case 'h':
+ sscanf (argv[++i], "%d", &opt.height);
+ break;
+ case 'i':
+ sscanf (argv[++i], "%d", &opt.iterations);
+ break;
+ case 'c':
+ sscanf (argv[++i], "%d", &opt.count);
+ break;
+ case 'f':
+ opt.drawMode = DM_FILL;
+ break;
+ case 's':
+ opt.drawMode = DM_STROKE;
+ break;
+ case 'b':
+ opt.drawMode = DM_BOTH;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return opt;
+}
+
+
+void printHelp () {
+ printf ("\t-w x : Set test surface width.\n");
+ printf ("\t-h x : Set test surface height.\n");
+ printf ("\t-i x : Set iterations count.\n");
+ printf ("\t-c x : Set shape occurence count.\n");
+ printf ("\t-f : Set shape draw mode to fill.\n");
+ printf ("\t-s : Set shape draw mode to stroke.\n");
+ printf ("\t-b : Set shape draw mode to fill and stroke.\n");
+}
+void outputResultsHeadRow (options_t* opt) {
+ printf ("__________________________________________________________________________________________________________\n");
+ printf ("| Test Name | Iter | Cpt | Resolution |DM | Min | Max | Average | Median | Std Deriv|\n");
+ printf ("|-----------------|------|------|-------------|---|----------|----------|----------|----------|----------|\n");
+}
+void outputResultsOnOneLine (options_t* opt, results_t* res) {
+ printf ("| %.15s | %4d | %4d | %4d x %4d | ",
+ opt->test_name, opt->iterations, opt->count, opt->width, opt->height);
+ switch (opt->drawMode) {
+ case DM_BOTH:
+ printf ("B | ");
+ break;
+ case DM_FILL:
+ printf ("F | ");
+ break;
+ case DM_STROKE:
+ printf ("S | ");
+ break;
+ }
+ printf ("%.6f | %.6f | %.6f | %.6f | %.6f |",
+ res->run_min, res->run_max, res->avg_time, res->median_time, res->std_deriv);
+}
+
+void outputResults (options_t* opt, results_t* res) {
+ printf ("Test name: %s\n", opt->test_name);
+ printf ("\nOptions\n");
+ printf ("=======\n");
+ printf ("Iterations = %d\n", opt->iterations);
+ printf ("Shape count = %d\n", opt->count);
+ printf ("Canva size = %d x %d\n", opt->width, opt->height);
+ switch (opt->drawMode) {
+ case DM_BOTH:
+ printf ("Draw Mode = FILL and STROKE\n");
+ break;
+ case DM_FILL:
+ printf ("Draw Mode = FILL\n");
+ break;
+ case DM_STROKE:
+ printf ("Draw Mode = STROKE\n");
+ break;
+ }
+ printf ("\nResults\n");
+ printf ("=======\n");
+ printf ("Minimum = %f (sec)\n", res->run_min);
+ printf ("Maximum = %f (sec)\n", res->run_max);
+ printf ("Average = %f (sec)\n", res->avg_time);
+ printf ("Median = %f (sec)\n", res->median_time);
+ printf ("Std reriv = %f \n", res->std_deriv);
+}
+
+double get_tick (void)
+{
+ struct timeval now;
+ gettimeofday (&now, NULL);
+ return (double)now.tv_sec + (double)now.tv_usec / 1000000.0;
+}
+double median_run_time (double data[], int n)
+{
+ double temp;
+ int i, j;
+ for (i = 0; i < n; i++)
+ for (j = i+1; j < n; j++)
+ {
+ if (data[i] > data[j])
+ {
+ temp = data[j];
+ data[j] = data[i];
+ data[i] = temp;
+ }
+ }
+ if (n % 2 == 0)
+ return (data[n/2] + data[n/2-1])/2;
+ else
+ return data[n/2];
+}
+double standard_deviation (const double data[], int n, double mean)
+{
+ double sum_deviation = 0.0;
+ int i;
+ for (i = 0; i < n; ++i)
+ sum_deviation += (data[i]-mean) * (data[i]-mean);
+ return sqrt (sum_deviation / n);
+}
+
+#endif // PERFTEST_H
diff --git a/tests/perf_test_0.c b/tests/perf_test_0.c
new file mode 100644
index 0000000..cff9f13
--- /dev/null
+++ b/tests/perf_test_0.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2018 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "vkengine.h"
+#include "vkvg.h"
+#include "vkh_device.h"
+#include "vkh_presenter.h"
+#include <sys/time.h>
+#include <stdlib.h>
+
+#include "perf-test.h"
+
+
+
+VkvgDevice device;
+/*VkvgSurface surf = NULL;
+
+void simple_paint () {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_paint(ctx);
+ vkvg_destroy(ctx);
+}
+void simple_rectangle_fill () {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,0,1,0,1);
+ vkvg_rectangle(ctx,100,100,200,200);
+ vkvg_fill(ctx);
+ vkvg_destroy(ctx);
+}
+void simple_rectangle_stroke () {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,0,0,1,1);
+ vkvg_set_line_width(ctx,10.f);
+ vkvg_rectangle(ctx,100,100,200,200);
+ vkvg_stroke(ctx);
+ vkvg_destroy(ctx);
+}*/
+
+vkvg_color_t getRadomColor () {
+ vkvg_color_t c = {
+ (float)rand()/RAND_MAX,
+ (float)rand()/RAND_MAX,
+ (float)rand()/RAND_MAX,
+ (float)rand()/RAND_MAX,
+ };
+}
+
+void drawRandomRectangle (options_t* opt, VkvgContext ctx) {
+ for (int i=0; i<opt->count; i++) {
+ vkvg_color_t c = getRadomColor();
+ vkvg_set_source_rgba(ctx, c.r, c.g, c.b, c.a);
+
+ float x = (float)rand()/RAND_MAX * opt->width - 10;
+ float y = (float)rand()/RAND_MAX * opt->height - 10;
+ float w = (float)rand()/RAND_MAX * 200 + 10;
+ float h = (float)rand()/RAND_MAX * 200 + 10;
+
+ vkvg_rectangle(ctx, x, y, w, h);
+ }
+ if (opt->drawMode == DM_BOTH)
+ vkvg_fill_preserve(ctx);
+ else if (opt->drawMode == DM_FILL)
+ vkvg_fill (ctx);
+ if (opt->drawMode & DM_STROKE)
+ vkvg_stroke (ctx);
+}
+
+results_t performTest (options_t* opt) {
+ results_t res = initResults();
+
+ double run_time_values[opt->iterations];
+ double start_time, stop_time, run_time, run_total = 0;
+
+ VkvgSurface surf = vkvg_surface_create(device, opt->width, opt->height);
+ void* ctx = vkvg_create(surf);
+
+ for (int i=0; i<opt->iterations; i++) {
+
+ start_time = get_tick();
+
+ drawRandomRectangle (opt, ctx);
+
+ stop_time = get_tick();
+
+ run_time = stop_time - start_time;
+ run_time_values[i] = run_time;
+
+ if (run_time < res.run_min)
+ res.run_min = run_time;
+ if (run_time > res.run_max)
+ res.run_max = run_time;
+ run_total += run_time;
+ }
+
+ vkvg_destroy (ctx);
+ vkvg_surface_destroy (surf);
+
+ res.avg_time = run_total / (double)opt->iterations;
+ res.median_time = median_run_time(run_time_values, opt->iterations);
+ res.std_deriv = standard_deviation(run_time_values,opt->iterations, res.avg_time);
+
+ return res;
+}
+
+int main(int argc, char *argv[]) {
+ srand(time(NULL));
+
+ options_t opt = initOptions(argc, argv);
+ opt.test_name = "vkvg rectangles and";
+
+ vk_engine_t* e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 1024, 800);
+ VkhPresenter r = e->renderer;
+
+ device = vkvg_device_create (r->dev->phy, r->dev->dev, r->qFam, 0);
+
+ results_t res = performTest (&opt);
+
+ //outputResults(&opt, &res);
+ outputResultsHeadRow(&opt);
+ outputResultsOnOneLine(&opt, &res);
+
+ vkvg_device_destroy (device);
+
+ vkengine_destroy (e);
+
+ return 0;
+}
diff --git a/tests/test_curves.c b/tests/test_curves.c
new file mode 100644
index 0000000..27eaaeb
--- /dev/null
+++ b/tests/test_curves.c
@@ -0,0 +1,1243 @@
+/*
+ * Copyright (c) 2018 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "vkengine.h"
+
+#include "vkvg.h"
+#include "string.h" //for nanosvg
+#define NANOSVG_IMPLEMENTATION // Expands implementation
+#include "nanosvg.h"
+#include "vkh_device.h"
+#include "vkh_presenter.h"
+
+#include "vkvg_context_internal.h"
+#include <sys/time.h>
+
+VkvgDevice device;
+VkvgSurface surf = NULL;
+
+static float m_approximation_scale = 1.0;
+static float m_angle_tolerance = 0.07;
+static float m_distance_tolerance = 1.0;
+static float m_cusp_limit = 0.05;
+static float curve_recursion_limit = 10;
+static float curve_collinearity_epsilon = 1.68;
+static float curve_angle_tolerance_epsilon = 0.001;
+static double frameTime = 0;
+
+static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
+ if (action == GLFW_RELEASE)
+ return;
+ float step = 0.01;
+
+ if (mods & GLFW_MOD_SHIFT)
+ step = -step;
+ if (mods & GLFW_MOD_CONTROL)
+ step *= 0.1;
+ switch (key) {
+ case GLFW_KEY_F1:
+ m_angle_tolerance += step;
+ break;
+ case GLFW_KEY_F2:
+ m_distance_tolerance += step;
+ break;
+ case GLFW_KEY_F3:
+ m_cusp_limit += step;
+ break;
+ case GLFW_KEY_F4:
+ curve_recursion_limit += step * 1000.0;
+ break;
+ case GLFW_KEY_F6:
+ curve_collinearity_epsilon += step;
+ break;
+ case GLFW_KEY_F7:
+ curve_angle_tolerance_epsilon += step;
+ break;
+ case GLFW_KEY_ESCAPE :
+ glfwSetWindowShouldClose(window, GLFW_TRUE);
+ break;
+ }
+}
+static void char_callback (GLFWwindow* window, uint32_t c){}
+static void mouse_move_callback(GLFWwindow* window, double x, double y){}
+static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){}
+
+void vkvg_test_gradient (VkvgContext ctx) {
+ VkvgPattern pat = vkvg_pattern_create_linear(100,0,300,0);
+ vkvg_set_line_width(ctx, 20);
+ vkvg_patter_add_color_stop(pat, 0, 1, 0, 0, 1);
+ vkvg_patter_add_color_stop(pat, 0.5, 0, 1, 0, 1);
+ vkvg_patter_add_color_stop(pat, 1, 0, 0, 1, 1);
+ vkvg_set_source (ctx, pat);
+ vkvg_rectangle(ctx,100,100,200,200);
+ vkvg_fill (ctx);
+ //vkvg_stroke (ctx);
+ vkvg_pattern_destroy (pat);
+}
+
+void vkvg_test_clip(VkvgContext ctx){
+ vkvg_move_to(ctx,10,10);
+ vkvg_line_to(ctx,400,150);
+ vkvg_line_to(ctx,900,10);
+ vkvg_line_to(ctx,700,450);
+ vkvg_line_to(ctx,900,750);
+ vkvg_line_to(ctx,500,650);
+ vkvg_line_to(ctx,100,800);
+ vkvg_line_to(ctx,150,400);
+ vkvg_clip(ctx);
+}
+void vkvg_test_fill(VkvgContext ctx){
+ vkvg_set_source_rgba(ctx,0.1,0.9,0.1,1.0);
+ vkvg_set_line_width(ctx,20);
+ vkvg_move_to(ctx,100,100);
+ vkvg_rel_line_to(ctx,100,100);
+ vkvg_rel_line_to(ctx,100,-50);
+ vkvg_rel_line_to(ctx,100,400);
+ vkvg_line_to(ctx,400,350);
+ vkvg_line_to(ctx,900,150);
+// vkvg_line_to(ctx,700,450);
+// vkvg_line_to(ctx,900,750);
+// vkvg_line_to(ctx,500,650);
+// vkvg_line_to(ctx,100,800);
+// vkvg_line_to(ctx,150,400);
+ vkvg_close_path(ctx);
+ vkvg_stroke(ctx);
+}
+void vkvg_test_fill_and_stroke (VkvgContext ctx){
+ vkvg_move_to (ctx, 100, 100);
+ vkvg_rel_line_to (ctx, 50, -80);
+ vkvg_rel_line_to (ctx, 50, 80);
+ //vkvg_close_path (ctx);
+
+ vkvg_move_to (ctx, 300, 100);
+ vkvg_rel_line_to (ctx, 50, -80);
+ vkvg_rel_line_to (ctx, 50, 80);
+ vkvg_close_path (ctx);
+
+ vkvg_set_line_width (ctx, 10.0);
+ vkvg_set_source_rgb (ctx, 0, 0, 1);
+ vkvg_fill_preserve (ctx);
+ //vkvg_fill(ctx);
+ vkvg_set_source_rgb (ctx, 0, 0, 0);
+ vkvg_stroke (ctx);
+}
+void vkvg_test_curves2 (VkvgContext ctx) {
+ vkvg_move_to (ctx, 400, 50);
+ vkvg_curve_to (ctx, 400, 50, 600,5,600,100);
+ vkvg_curve_to (ctx, 600, 5, 800,50,800,50);
+
+ vkvg_move_to (ctx, 400, 150);
+ vkvg_curve_to (ctx, 0, 0, 800, 0, 300, 350);
+ vkvg_curve_to (ctx, 500, 500, 300, 0, 500, 700);
+
+ //vkvg_curve_to (ctx, 1000, 100, 100, 800, 1000, 800);
+ //vkvg_curve_to (ctx, 1000, 500, 700, 500, 700, 100);
+ //vkvg_close_path(ctx);
+
+ //vkvg_set_source_rgba (ctx, 0.5,0.0,1.0,0.5);
+ //vkvg_fill_preserve(ctx);
+
+ vkvg_set_source_rgba (ctx, 0,0,0,0.5);
+ vkvg_set_line_width(ctx, 40);
+ vkvg_stroke(ctx);
+}
+void vkvg_test_curves (VkvgContext ctx){
+
+ vkvg_set_line_width(ctx, 10);
+ vkvg_set_source_rgb (ctx, 0,0,0);
+
+ vkvg_set_source_rgba (ctx, 0.5,0.0,1.0,0.5);
+ vkvg_move_to(ctx,100,100);
+ vkvg_line_to(ctx,200,100);
+ vkvg_curve_to(ctx,250,100,300,150,300,200);
+ vkvg_line_to(ctx,300,300);
+ vkvg_curve_to(ctx,300,350,250,400,200,400);
+ vkvg_line_to(ctx,100,400);
+ vkvg_curve_to(ctx,50,400,10,350,10,300);
+ vkvg_line_to(ctx,10,200);
+ vkvg_curve_to(ctx,10,150,50,100,100,100);
+ vkvg_close_path(ctx);
+ //vkvg_curve_to(ctx, 150,100,200,150,200,200);
+ vkvg_fill_preserve(ctx);
+ vkvg_set_source_rgba (ctx, 0,0,0,0.5);
+ vkvg_stroke(ctx);
+
+ vkvg_arc(ctx, 150, 100, 100, 0, M_PI*2);
+ vkvg_fill(ctx);
+ vkvg_arc(ctx, 200, 200, 100, 0, M_PI*2);
+ vkvg_stroke(ctx);
+
+ vkvg_set_line_width(ctx, 90);
+ vkvg_arc(ctx, 120, 500, 100, 0, M_PI*2);
+ vkvg_stroke(ctx);
+
+}
+void vkvg_test_stroke(VkvgContext ctx){
+ vkvg_set_line_width(ctx, 2);
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_move_to(ctx,200.5,200.5);
+ vkvg_line_to(ctx,400.5,200.5);
+ vkvg_line_to(ctx,400.5,400.5);
+ vkvg_line_to(ctx,200.5,400.5);
+ vkvg_close_path(ctx);
+ vkvg_stroke_preserve(ctx);
+ vkvg_set_source_rgba(ctx,0,0.2,0.35,1);
+ vkvg_fill(ctx);
+ vkvg_set_source_rgba(ctx,0.5,1,0,1);
+ vkvg_move_to(ctx,300.5,300.5);
+ vkvg_line_to(ctx,500.5,300.5);
+ vkvg_line_to(ctx,500.5,500.5);
+ vkvg_line_to(ctx,300.5,500.5);
+ vkvg_close_path(ctx);
+ vkvg_stroke(ctx);
+ vkvg_set_line_width(ctx, 40);
+ vkvg_set_source_rgba(ctx,0.5,0.6,1,1.0);
+ vkvg_move_to(ctx,700,475);
+ vkvg_line_to(ctx,400,475);
+ vkvg_stroke(ctx);
+ vkvg_set_source_rgba(ctx,0,0.5,0.5,0.5);
+ vkvg_move_to(ctx,300,200);
+ vkvg_arc(ctx, 200,200,100,0, M_PI);
+ vkvg_stroke(ctx);
+
+ vkvg_set_line_width(ctx, 20);
+ vkvg_set_source_rgba(ctx,0.1,0.1,0.1,0.5);
+ vkvg_move_to(ctx,100,60);
+ vkvg_line_to(ctx,400,600);
+ vkvg_stroke(ctx);
+}
+void test_text (VkvgContext ctx) {
+ int size = 19;
+ int penY = 50;
+ int penX = 10;
+
+ /*vkvg_rectangle(ctx,30,0,100,400);
+ vkvg_clip(ctx);*/
+
+ //vkvg_select_font_face(ctx, "/usr/local/share/fonts/DroidSansMono.ttf");
+ //vkvg_select_font_face(ctx, "/usr/share/fonts/truetype/unifont/unifont.ttf");
+
+ vkvg_set_font_size(ctx,12);
+ vkvg_select_font_face(ctx, "droid");
+ vkvg_font_extents_t fe;
+ vkvg_font_extents (ctx,&fe);
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1);
+ vkvg_text_extents_t te;
+ vkvg_text_extents(ctx,"abcdefghijk",&te);
+ vkvg_show_text (ctx,"abcdefghijk");
+ penX+= te.x_advance;
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"*abcdefghijk2");
+ penY+=2*size;
+
+
+ vkvg_select_font_face(ctx, "times");
+ vkvg_set_source_rgba(ctx,0.9,0.7,0.7,1);
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
+ penY+=size;
+
+
+
+ vkvg_select_font_face(ctx, "droid");
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"lmnopqrstuvwxyz123456789");
+ penY+=size;
+
+
+
+ vkvg_select_font_face(ctx, "times:bold");
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
+ penY+=size;
+
+
+ vkvg_select_font_face(ctx, "droid");
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ penY+=size;
+
+
+
+ vkvg_select_font_face(ctx, "arial:italic");
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"abcdefghijklmnopqrstuvwxyz");
+ penY+=size;
+
+
+ vkvg_select_font_face(ctx, "arial");
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ penY+=size;
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"this is a test");
+ penY+=size;
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"this is another test to see if label is working");
+ penY+=size;
+
+ vkvg_select_font_face(ctx, "mono");
+ vkvg_move_to(ctx, penX,penY);
+ vkvg_show_text (ctx,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ penY+=size;
+
+ vkvg_move_to(ctx, 80,400);
+ vkvg_show_text (ctx,"Ленивый рыжий кот");
+
+
+ /*vkvg_move_to(ctx, 150,250);
+ vkvg_show_text (ctx,"test string é€");
+ vkvg_move_to(ctx, 150,300);
+ vkvg_show_text (ctx,"كسول الزنجبيل القط");
+ vkvg_move_to(ctx, 150,350);
+ vkvg_show_text (ctx,"懶惰的姜貓");*/
+
+ //vkvg_show_text (ctx,"ABCDABCD");
+ //vkvg_show_text (ctx,"j");
+}
+void vkvg_test_stroke2(VkvgContext ctx){
+ vkvg_set_line_width(ctx,20);
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_move_to(ctx,200,200);
+ vkvg_line_to(ctx,400,200);
+ vkvg_line_to(ctx,400,400);
+ vkvg_line_to(ctx,200,400);
+ vkvg_close_path(ctx);
+ vkvg_stroke(ctx);
+ vkvg_set_source_rgba(ctx,0.5,1,0,1);
+ vkvg_move_to(ctx,300,300);
+ vkvg_line_to(ctx,500,300);
+ vkvg_line_to(ctx,500,500);
+ vkvg_line_to(ctx,300,500);
+ vkvg_close_path(ctx);
+ vkvg_stroke(ctx);
+ vkvg_set_line_width(ctx,10);
+ vkvg_set_source_rgba(ctx,0.5,0.6,1,1);
+ vkvg_move_to(ctx,700,475);
+ vkvg_line_to(ctx,400,475);
+ vkvg_stroke(ctx);
+ vkvg_set_source_rgba(ctx,1,0,1,1);
+ vkvg_move_to(ctx,700,500);
+
+ vkvg_arc(ctx, 600,500,100,M_PI, 2.0*M_PI);
+ vkvg_stroke(ctx);
+
+
+ vkvg_set_line_width(ctx,20);
+ vkvg_set_source_rgba(ctx,1,1,0,1);
+ vkvg_move_to(ctx,100,50);
+ vkvg_line_to(ctx,400,50);
+ vkvg_stroke(ctx);
+}
+void vkvg_test_fill2(VkvgContext ctx){
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_move_to(ctx,200,200);
+ vkvg_line_to(ctx,250,150);
+ vkvg_line_to(ctx,200,100);
+ vkvg_line_to(ctx,300,150);
+ vkvg_line_to(ctx,700,100);
+ vkvg_line_to(ctx,400,200);
+ vkvg_line_to(ctx,400,400);
+ vkvg_line_to(ctx,200,400);
+ vkvg_line_to(ctx,300,300);
+ vkvg_close_path(ctx);
+ vkvg_fill(ctx);
+}
+void test_img_surface () {
+ VkvgContext ctx = vkvg_create(surf);
+ VkvgSurface imgSurf;// = vkvg_surface_create_from_image(device, "/mnt/data/images/blason.png");
+ //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/2000px-Tux.svg.png");
+ //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/path2674.png");
+ //VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/horse-black-head-shape-of-a-chess-piece_318-52446.jpg");
+ /*vkvg_set_source_surface(ctx, imgSurf, 200, 200);
+ vkvg_paint(ctx);
+ vkvg_set_source_surface(ctx, imgSurf, 400, 400);
+ vkvg_paint(ctx);
+ vkvg_flush(ctx);
+ vkvg_surface_destroy(imgSurf);*/
+
+ imgSurf = vkvg_surface_create_from_image(device, "/mnt/data/images/miroir.jpg");
+ fflush(stdout);
+ vkvg_set_source_surface(ctx, imgSurf, 0, 0);
+ vkvg_paint(ctx);
+ //vkvg_flush(ctx);
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+
+ vkvg_surface_destroy(imgSurf);
+ vkvg_destroy(ctx);
+}
+void test_line_caps (VkvgContext ctx) {
+
+ float x = 20, y = 20, dx = 30, dy = 60;
+
+ //vkvg_scale(ctx,5,5);
+ vkvg_set_line_width(ctx,26);
+ vkvg_set_source_rgba(ctx,0,0,0,1);
+ vkvg_move_to(ctx,x,y);
+ vkvg_rel_line_to(ctx,0,dy);
+ vkvg_stroke(ctx);
+ vkvg_set_line_cap(ctx,VKVG_LINE_CAP_SQUARE);
+ vkvg_move_to(ctx,x+dx,y);
+ vkvg_rel_line_to(ctx,0,dy);
+ vkvg_stroke(ctx);
+ vkvg_set_line_cap(ctx,VKVG_LINE_CAP_ROUND);
+ vkvg_move_to(ctx,x+2*dx,y);
+ vkvg_rel_line_to(ctx,0,dy);
+ vkvg_rel_move_to(ctx,dx,-dy);
+ vkvg_rel_line_to(ctx,dx,dy);
+ vkvg_rel_move_to(ctx,dx,-dy/2);
+ vkvg_rel_line_to(ctx,dx,0);
+ vkvg_rel_move_to(ctx,dx,dy/2);
+ vkvg_rel_line_to(ctx,dx,-dy);
+ vkvg_rel_move_to(ctx,dx,dy);
+ vkvg_rel_line_to(ctx,0,-dy);
+ vkvg_rel_move_to(ctx,2*dx,dy);
+ vkvg_rel_line_to(ctx,-dx,-dy);
+ vkvg_rel_move_to(ctx,3*dx,dy/2);
+ vkvg_rel_line_to(ctx,-dx,0);
+ //vkvg_rel_line_to(ctx,0,-dy);
+ //vkvg_rel_move_to(ctx,dx,dy/2);
+ //vkvg_rel_line_to(ctx,dx,0);
+ vkvg_stroke(ctx);
+
+ vkvg_set_line_cap(ctx,VKVG_LINE_CAP_BUTT);
+ vkvg_set_line_width(ctx,1);
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_move_to(ctx,x,y);
+ vkvg_rel_line_to(ctx,0,dy);
+ vkvg_rel_move_to(ctx,dx,-dy);
+ vkvg_rel_line_to(ctx,0,dy);
+ vkvg_rel_move_to(ctx,dx,-dy);
+ vkvg_rel_line_to(ctx,0,dy);
+ vkvg_stroke(ctx);
+}
+void test_line_join (VkvgContext ctx){
+ float x = 50, y = 150, dx = 150, dy = 140;
+
+ //vkvg_scale(ctx,2,2);
+
+ vkvg_set_line_width(ctx,50);
+ vkvg_set_source_rgba(ctx,0,0,0,1);
+
+
+ vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND);
+ //vkvg_rectangle(ctx,x,y,dx,dy);
+
+ vkvg_move_to(ctx,x,y);
+ vkvg_rel_line_to(ctx,50,-30);
+ vkvg_rel_line_to(ctx,50,0);
+ vkvg_rel_line_to(ctx,50,30);
+ vkvg_rel_line_to(ctx,0,60);
+ vkvg_rel_line_to(ctx,-50,70);
+ vkvg_rel_line_to(ctx,-50,0);
+ vkvg_rel_line_to(ctx,-50,-70);
+ vkvg_close_path(ctx);
+ vkvg_stroke(ctx);
+
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_move_to(ctx,x+200,y);
+ vkvg_rel_line_to(ctx,50,70);
+ vkvg_rel_line_to(ctx,50,0);
+ vkvg_rel_line_to(ctx,50,-70);
+ vkvg_rel_line_to(ctx,0,-60);
+ vkvg_rel_line_to(ctx,-50,-30);
+ vkvg_rel_line_to(ctx,-50,0);
+ vkvg_rel_line_to(ctx,-50,30);
+ vkvg_close_path(ctx);
+ vkvg_stroke(ctx);
+
+ vkvg_move_to(ctx,x,y);
+ vkvg_rel_line_to(ctx,50,-30);
+ vkvg_rel_line_to(ctx,50,0);
+ vkvg_rel_line_to(ctx,50,30);
+ vkvg_rel_line_to(ctx,0,60);
+ vkvg_rel_line_to(ctx,-50,70);
+ vkvg_rel_line_to(ctx,-50,0);
+ vkvg_rel_line_to(ctx,-50,-70);
+ vkvg_close_path(ctx);
+ vkvg_stroke(ctx);
+
+// vkvg_rel_line_to(ctx,dx,-dy);
+// vkvg_rel_line_to(ctx,dx,dy);
+// vkvg_stroke(ctx);
+// vkvg_set_line_join(ctx,VKVG_LINE_JOIN_BEVEL);
+// vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5));
+// vkvg_rel_line_to(ctx,dx,-dy);
+// vkvg_rel_line_to(ctx,dx,dy);
+// vkvg_stroke(ctx);
+// vkvg_set_line_join(ctx,VKVG_LINE_JOIN_ROUND);
+// vkvg_rel_move_to(ctx,-dx*2,abs(dy*1.5));
+// vkvg_rel_line_to(ctx,dx,-dy);
+// vkvg_rel_line_to(ctx,dx,dy);
+// vkvg_stroke(ctx);
+ vkvg_set_line_join(ctx,VKVG_LINE_JOIN_MITER);
+}
+void test_colinear () {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1);
+ vkvg_paint(ctx);
+
+ vkvg_set_source_rgba(ctx,0,0,0,0.5);
+ vkvg_set_line_width(ctx,30);
+
+ vkvg_move_to(ctx,100,100);
+ vkvg_line_to(ctx,100,200);
+ vkvg_line_to(ctx,100,300);
+ //vkvg_line_to(ctx,100,0);
+ vkvg_stroke(ctx);
+
+ vkvg_destroy(ctx);
+}
+
+void multi_test1 () {
+ VkvgSurface surf2 = vkvg_surface_create (device,800,800);;
+ VkvgContext ctx = vkvg_create (surf2);
+
+ vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0);
+ vkvg_paint(ctx);
+
+ vkvg_test_fill(ctx);
+ vkvg_test_fill2(ctx);
+
+
+ //test_line_join(ctx);
+
+ //vkvg_test_clip(ctx);
+
+ //test_text(ctx);
+
+
+ vkvg_test_stroke(ctx);
+
+ vkvg_translate(ctx, 100,50);
+// vkvg_rotate(ctx, 0.2);
+ //vkvg_scale(ctx, 2,2);
+
+
+ //vkvg_test_gradient (ctx);
+
+ vkvg_test_curves(ctx);
+ vkvg_test_curves2(ctx);
+
+ /*vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR);
+ vkvg_rectangle(ctx,100,100,300,300);
+ vkvg_fill(ctx);
+ vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);*/
+
+ //test_img_surface(ctx);
+ //test_line_caps(ctx);
+
+ vkvg_destroy(ctx);
+ ctx = vkvg_create(surf);
+
+ vkvg_set_source_rgba(ctx,1.0,0.0,0.0,1);
+ vkvg_paint(ctx);
+// vkvg_set_source_rgba(ctx,0.0,0.0,1.0,1);
+// vkvg_rectangle(ctx,100,100,500,500);
+// vkvg_fill(ctx);
+
+ VkvgPattern pat = vkvg_pattern_create_for_surface(surf2);
+ vkvg_pattern_set_extend(pat, VKVG_EXTEND_REFLECT);
+ vkvg_pattern_set_filter(pat, VKVG_FILTER_BILINEAR);
+ vkvg_set_source (ctx, pat);
+ //vkvg_rectangle(ctx,100,100,400,400);
+ //vkvg_fill(ctx);
+ vkvg_paint(ctx);
+ vkvg_translate(ctx,200,200);
+ vkvg_paint(ctx);
+ vkvg_rotate(ctx,0.7);
+ vkvg_paint(ctx);
+ vkvg_pattern_destroy (pat);
+ vkvg_destroy(ctx);
+ vkvg_surface_destroy(surf2);
+}
+
+void cairo_test_fill_rule (VkvgContext cr){
+ vkvg_set_line_width (cr, 6);
+
+ //vkvg_scale(cr,3,3);
+ vkvg_set_source_rgba(cr,1,0,0,1);
+ vkvg_move_to(cr,50,150);
+ vkvg_rel_line_to(cr,50,70);
+ vkvg_rel_line_to(cr,50,0);
+ vkvg_rel_line_to(cr,50,-70);
+ vkvg_rel_line_to(cr,0,-60);
+ vkvg_rel_line_to(cr,-50,-30);
+ vkvg_rel_line_to(cr,-50,0);
+ vkvg_rel_line_to(cr,-50,30);
+ vkvg_close_path(cr);
+
+
+// vkvg_set_line_join(cr,VKVG_LINE_JOIN_ROUND);
+ vkvg_set_source_rgb (cr, 0, 0.7, 0);
+ vkvg_rectangle (cr, 12, 12, 232, 70);
+ //vkvg_stroke (cr);
+// vkvg_new_sub_path (cr);
+ vkvg_arc (cr, 64, 64, 40, 0, M_PI*2);
+ //vkvg_close_path(cr);
+
+ vkvg_new_sub_path (cr);
+ vkvg_arc_negative (cr, 192, 64, 40, 2*M_PI, 0);
+ //vkvg_close_path(cr);
+
+ //vkvg_rectangle (cr, 30, 30, 20, 200);
+ //vkvg_rectangle (cr, 130, 30, 20, 200);
+ //vkvg_set_fill_rule (cr, vkvg_FILL_RULE_EVEN_ODD);
+
+ vkvg_fill_preserve(cr);
+
+ vkvg_set_source_rgb (cr, 0, 0, 0);
+ vkvg_stroke (cr);
+}
+void cairo_test_text (VkvgContext cr) {
+ vkvg_text_extents_t extents;
+
+ const char *utf8 = "vkvg";
+ float x,y;
+
+ vkvg_select_font_face (cr, "times");
+ vkvg_set_font_size (cr, 100.0);
+ vkvg_text_extents (cr, utf8, &extents);
+ vkvg_set_source_rgb(cr,0,0,0);
+
+ x=25.0;
+ y=150.0;
+
+ vkvg_move_to (cr, x,y);
+ vkvg_show_text (cr, utf8);
+
+ /* draw helping lines */
+ vkvg_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
+ vkvg_set_line_width (cr, 6.0);
+ vkvg_arc (cr, x, y, 10.0, 0, 2*M_PI);
+ vkvg_fill (cr);
+ vkvg_move_to (cr, x,y);
+ vkvg_rel_line_to (cr, 0, -extents.height);
+ vkvg_rel_line_to (cr, extents.width, 0);
+ vkvg_rel_line_to (cr, extents.x_bearing, -extents.y_bearing);
+ vkvg_stroke (cr);
+}
+void cairo_test_clip (VkvgContext cr){
+ vkvg_arc (cr, 128.0, 128.0, 76.8, 0, 2 * M_PI);
+ vkvg_clip (cr);
+ //vkvg_new_path (cr); /* current path is not
+ // consumed by vkvg_clip() */
+ vkvg_set_source_rgba(cr, 0, 0, 0, 1);
+ vkvg_rectangle (cr, 0, 0, 256, 256);
+ vkvg_fill (cr);
+ vkvg_set_source_rgba (cr, 0, 1, 0, 1);
+ vkvg_move_to (cr, -100, -100);
+ vkvg_line_to (cr, 256, 256);
+ vkvg_move_to (cr, 356, -100);
+ vkvg_line_to (cr, 0, 256);
+ vkvg_set_line_width (cr, 10.0);
+ vkvg_stroke (cr);
+}
+void cairo_test_curves (VkvgContext cr){
+ float x=25.6, y=128.0;
+ float x1=102.4, y1=230.4,
+ x2=153.6, y2=25.6,
+ x3=230.4, y3=128.0;
+
+ vkvg_set_source_rgb (cr, 0, 0, 0);
+ vkvg_move_to (cr, x, y);
+ vkvg_curve_to (cr, x1, y1, x2, y2, x3, y3);
+
+ vkvg_set_line_width (cr, 10.0);
+ vkvg_stroke (cr);
+
+ vkvg_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
+ vkvg_set_line_width (cr, 6.0);
+ vkvg_move_to (cr,x,y); vkvg_line_to (cr,x1,y1);
+ vkvg_move_to (cr,x2,y2); vkvg_line_to (cr,x3,y3);
+ vkvg_stroke (cr);
+}
+void cairo_test_rounded_rect (VkvgContext cr) {
+ /* a custom shape that could be wrapped in a function */
+ float x0 = 25.6, /* parameters like vkvg_rectangle */
+ y0 = 25.6,
+ rect_width = 204.8,
+ rect_height = 204.8,
+ radius = 102.4; /* and an approximate curvature radius */
+
+ float x1,y1;
+
+ x1=x0+rect_width;
+ y1=y0+rect_height;
+ if (!rect_width || !rect_height)
+ return;
+ if (rect_width/2<radius) {
+ if (rect_height/2<radius) {
+ vkvg_move_to (cr, x0, (y0 + y1)/2);
+ vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
+ vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
+ vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
+ vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
+ } else {
+ vkvg_move_to (cr, x0, y0 + radius);
+ vkvg_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
+ vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+ vkvg_line_to (cr, x1 , y1 - radius);
+ vkvg_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
+ vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
+ }
+ } else {
+ if (rect_height/2<radius) {
+ vkvg_move_to (cr, x0, (y0 + y1)/2);
+ vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
+ vkvg_line_to (cr, x1 - radius, y0);
+ vkvg_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
+ vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+ vkvg_line_to (cr, x0 + radius, y1);
+ vkvg_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
+ } else {
+ vkvg_move_to (cr, x0, y0 + radius);
+ vkvg_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
+ vkvg_line_to (cr, x1 - radius, y0);
+ vkvg_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
+ vkvg_line_to (cr, x1 , y1 - radius);
+ vkvg_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
+ vkvg_line_to (cr, x0 + radius, y1);
+ vkvg_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
+ }
+ }
+ vkvg_close_path (cr);
+
+ vkvg_set_source_rgb (cr, 0.5, 0.5, 1);
+ vkvg_fill_preserve (cr);
+ vkvg_set_source_rgba (cr, 0.5, 0, 0, 0.5);
+ vkvg_set_line_width (cr, 10.0);
+ vkvg_stroke (cr);
+}
+void cairo_test_fill_and_stroke2 (VkvgContext cr){
+ vkvg_move_to (cr, 128.0, 25.6);
+ vkvg_line_to (cr, 230.4, 230.4);
+ vkvg_rel_line_to (cr, -102.4, 0.0);
+ vkvg_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
+ vkvg_close_path (cr);
+
+ vkvg_move_to (cr, 64.0, 25.6);
+ vkvg_rel_line_to (cr, 51.2, 51.2);
+ vkvg_rel_line_to (cr, -51.2, 51.2);
+ vkvg_rel_line_to (cr, -51.2, -51.2);
+ vkvg_close_path (cr);
+
+ /*vkvg_translate(cr,100,100);
+ vkvg_move_to (cr, 100, 100);
+ vkvg_line_to(cr,300,300);
+ vkvg_line_to(cr,100,300);*/
+
+
+ vkvg_set_line_width (cr, 10.0);
+ vkvg_set_source_rgb (cr, 0, 0, 1);
+ vkvg_fill_preserve (cr);
+ vkvg_set_source_rgb (cr, 0, 0, 0);
+ vkvg_stroke (cr);
+}
+void cairo_print_arc_neg (VkvgContext cr){
+ float xc = 128.0;
+ float yc = 128.0;
+ float radius = 100.0;
+ float angle1 = 45.0 * (M_PI/180.0); /* angles are specified */
+ float angle2 = 180.0 * (M_PI/180.0); /* in radians */
+
+ vkvg_set_source_rgba(cr, 0, 0, 0, 1);
+ vkvg_set_line_width (cr, 10.0);
+ vkvg_arc_negative (cr, xc, yc, radius, angle1, angle2);
+ vkvg_stroke (cr);
+
+ /* draw helping lines */
+ vkvg_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
+ vkvg_set_line_width (cr, 6.0);
+
+ vkvg_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
+ vkvg_fill (cr);
+
+ vkvg_arc (cr, xc, yc, radius, angle1, angle1);
+ vkvg_line_to (cr, xc, yc);
+ vkvg_arc (cr, xc, yc, radius, angle2, angle2);
+ //vkvg_line_to (cr, xc, yc);
+ vkvg_stroke (cr);
+
+}
+void cairo_test_line_caps (VkvgContext cr) {
+ vkvg_set_source_rgb (cr, 0, 0, 0);
+ vkvg_set_line_width (cr, 30.0);
+ vkvg_set_line_cap (cr, VKVG_LINE_CAP_BUTT); /* default */
+ vkvg_move_to (cr, 64.0, 50.0); vkvg_line_to (cr, 64.0, 200.0);
+ vkvg_stroke (cr);
+ vkvg_set_line_cap (cr, VKVG_LINE_CAP_ROUND);
+ vkvg_move_to (cr, 128.0, 50.0); vkvg_line_to (cr, 128.0, 200.0);
+ vkvg_stroke (cr);
+ vkvg_set_line_cap (cr, VKVG_LINE_CAP_SQUARE);
+ vkvg_move_to (cr, 192.0, 50.0); vkvg_line_to (cr, 192.0, 200.0);
+ vkvg_stroke (cr);
+
+ /* draw helping lines */
+ vkvg_set_source_rgb (cr, 1, 0.2, 0.2);
+ vkvg_set_line_width (cr, 2.56);
+ vkvg_move_to (cr, 64.0, 50.0); vkvg_line_to (cr, 64.0, 200.0);
+ vkvg_move_to (cr, 128.0, 50.0); vkvg_line_to (cr, 128.0, 200.0);
+ vkvg_move_to (cr, 192.0, 50.0); vkvg_line_to (cr, 192.0, 200.0);
+ vkvg_stroke (cr);
+}
+void cairo_test_line_joins (VkvgContext cr) {
+ vkvg_set_source_rgb (cr, 0, 0, 0);
+ vkvg_set_line_width (cr, 40.96);
+ vkvg_move_to (cr, 76.8, 84.48);
+ vkvg_rel_line_to (cr, 51.2, -51.2);
+ vkvg_rel_line_to (cr, 51.2, 51.2);
+ vkvg_set_line_join (cr, VKVG_LINE_JOIN_MITER); /* default */
+ vkvg_stroke (cr);
+
+ vkvg_move_to (cr, 76.8, 161.28);
+ vkvg_rel_line_to (cr, 51.2, -51.2);
+ vkvg_rel_line_to (cr, 51.2, 51.2);
+ vkvg_set_line_join (cr, VKVG_LINE_JOIN_BEVEL);
+ vkvg_stroke (cr);
+
+ vkvg_move_to (cr, 76.8, 238.08);
+ vkvg_rel_line_to (cr, 51.2, -51.2);
+ vkvg_rel_line_to (cr, 51.2, 51.2);
+ vkvg_set_line_join (cr, VKVG_LINE_JOIN_ROUND);
+ vkvg_stroke (cr);
+}
+void cairo_print_arc (VkvgContext cr) {
+ float xc = 128.0;
+ float yc = 128.0;
+ float radius = 100.0;
+ float angle1 = 45.0 * (M_PI/180.0); /* angles are specified */
+ float angle2 = 180.0 * (M_PI/180.0); /* in radians */
+
+ vkvg_set_source_rgba(cr, 0, 0, 0, 1);
+ vkvg_set_line_width (cr, 10.0);
+ vkvg_arc (cr, xc, yc, radius, angle1, angle2);
+ vkvg_stroke (cr);
+
+ /* draw helping lines */
+ vkvg_set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
+ vkvg_set_line_width (cr, 6.0);
+
+ vkvg_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
+ vkvg_fill (cr);
+
+ vkvg_arc (cr, xc, yc, radius, angle1, angle1);
+ vkvg_line_to (cr, xc, yc);
+ vkvg_arc (cr, xc, yc, radius, angle2, angle2);
+ vkvg_stroke (cr);
+}
+static float rotation = 0.f;
+void cairo_tests () {
+ rotation+=0.01f;
+
+ vkvg_matrix_t mat;
+ vkvg_matrix_init_translate (&mat, 512,400);
+ vkvg_matrix_rotate(&mat,rotation);
+ vkvg_matrix_translate(&mat,-512,-400);
+
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,0.7,0.7,0.7,1);
+ vkvg_paint(ctx);
+
+ vkvg_set_matrix(ctx,&mat);
+ /*
+ vkvg_set_source_rgba(ctx,0,1,0,1);
+ vkvg_rectangle(ctx,0,0,600,600);
+ vkvg_fill(ctx);
+
+ vkvg_clip(ctx);
+
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_paint(ctx);
+ //vkvg_rectangle(ctx,00,00,1024,800);
+ //vkvg_fill(ctx);
+
+ vkvg_reset_clip(ctx);
+ vkvg_set_source_rgba(ctx,0,0,1,1);
+ vkvg_set_line_width(ctx,20);
+ vkvg_move_to(ctx,0,0);
+ vkvg_rel_line_to(ctx,800,800);
+ vkvg_stroke(ctx);*/
+
+// cairo_test_clip(ctx);
+// vkvg_reset_clip(ctx);
+ //test_img_surface (ctx);
+
+ cairo_print_arc(ctx);
+
+ vkvg_translate(ctx,200,0);
+ cairo_test_fill_rule(ctx);
+
+ vkvg_translate(ctx,250,0);
+ cairo_test_rounded_rect(ctx);
+
+
+/*
+ vkvg_set_operator(ctx, VKVG_OPERATOR_CLEAR);
+ vkvg_rectangle(ctx,100,100,500,500);
+ vkvg_fill(ctx);
+ vkvg_set_operator(ctx, VKVG_OPERATOR_OVER);
+*/
+
+
+ vkvg_translate(ctx,-450,250);
+ cairo_test_fill_and_stroke2(ctx);
+
+ vkvg_translate(ctx,250,0);
+ cairo_print_arc_neg(ctx);
+
+ vkvg_translate(ctx,250,0);
+ cairo_test_text(ctx);
+
+ vkvg_translate(ctx,-500,250);
+ cairo_test_curves(ctx);
+
+ vkvg_translate(ctx,250,0);
+ cairo_test_line_joins(ctx);
+
+ vkvg_translate(ctx,250,0);
+ cairo_test_line_caps(ctx);
+
+ vkvg_destroy(ctx);
+}
+
+void test_grad_transforms () {
+ VkvgContext ctx = vkvg_create(surf);
+
+ vkvg_translate(ctx,-100,-100);
+ vkvg_rotate(ctx,1.5);
+ //vkvg_translate(ctx,100,100);
+
+ //vkvg_scale(ctx,0.2,0.2);
+ VkvgPattern pat = vkvg_pattern_create_linear(0,0,200,0);
+ vkvg_set_line_width(ctx, 20);
+ vkvg_patter_add_color_stop(pat, 0, 1, 0, 0, 1);
+ vkvg_patter_add_color_stop(pat, 0.5, 0, 1, 0, 1);
+ vkvg_patter_add_color_stop(pat, 1, 0, 0, 1, 1);
+ vkvg_set_source (ctx, pat);
+ vkvg_rectangle(ctx,0,0,200,200);
+ vkvg_fill (ctx);
+ //vkvg_stroke (ctx);
+ vkvg_pattern_destroy (pat);
+
+ vkvg_destroy(ctx);
+}
+
+void svg_set_color (VkvgContext ctx, uint32_t c, float alpha) {
+ float a = (c >> 24 & 255) / 255.f;
+ float b = (c >> 16 & 255) / 255.f;
+ float g = (c >> 8 & 255) / 255.f;
+ float r = (c & 255) / 255.f;
+ vkvg_set_source_rgba(ctx,r,g,b,a*alpha);
+}
+
+void test_svg (VkvgContext ctx) {
+ //VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,0.5,0.5,0.5,1);
+ vkvg_paint(ctx);
+
+ NSVGimage* svg;
+ NSVGshape* shape;
+ NSVGpath* path;
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/tux.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/world.svg", "px", 96);
+ svg = nsvgParseFromFile("/mnt/data/images/svg/tiger.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/koch_curve.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/diamond1.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/diamond2.svg", "px", 96);
+ //svg = nsvgParseFromFile("/home/jp/yahweh-protosinaitic.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/WMD-biological.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/Skull_and_crossbones.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/IconAlerte.svg", "px", 96);
+ //svg = nsvgParseFromFile("/mnt/data/images/svg/Svg_example4.svg", "px", 96);
+
+ //vkvg_scale(ctx, 3,3);
+ vkvg_set_source_rgba(ctx,0.0,0.0,0.0,1);
+
+ for (shape = svg->shapes; shape != NULL; shape = shape->next) {
+
+ vkvg_new_path(ctx);
+
+ float o = shape->opacity;
+
+ vkvg_set_line_width(ctx, shape->strokeWidth);
+
+ for (path = shape->paths; path != NULL; path = path->next) {
+ float* p = path->pts;
+ vkvg_move_to(ctx, p[0],p[1]);
+ for (int i = 1; i < path->npts-2; i += 3) {
+ p = &path->pts[i*2];
+ vkvg_curve_to(ctx, p[0],p[1], p[2],p[3], p[4],p[5]);
+ }
+ if (path->closed)
+ vkvg_close_path(ctx);
+ }
+
+ if (shape->fill.type == NSVG_PAINT_COLOR)
+ svg_set_color(ctx, shape->fill.color, o);
+ else if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT){
+ NSVGgradient* g = shape->fill.gradient;
+ svg_set_color(ctx, g->stops[0].color, o);
+ }
+
+ if (shape->fill.type != NSVG_PAINT_NONE){
+ if (shape->stroke.type == NSVG_PAINT_NONE){
+ vkvg_fill(ctx);
+ continue;
+ }
+ vkvg_fill_preserve (ctx);
+ }
+
+ if (shape->stroke.type == NSVG_PAINT_COLOR)
+ svg_set_color(ctx, shape->stroke.color, o);
+ else if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT){
+ NSVGgradient* g = shape->stroke.gradient;
+ svg_set_color(ctx, g->stops[0].color, o);
+ }
+
+ vkvg_stroke(ctx);
+ }
+
+ nsvgDelete(svg);
+
+
+ //vkvg_destroy(ctx);
+}
+
+void print_float (VkvgContext ctx){
+ char str[50];
+ float penY = 20, penX = 10, dy = 18;
+
+ vkvg_set_source_rgb(ctx,1,1,1);
+ vkvg_set_font_size(ctx,14 );
+ vkvg_select_font_face(ctx, "mono");
+
+ sprintf (str, "frame (µs): %.0lf", frameTime);
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+ penY += dy;
+ sprintf (str, "fps: %lf", floor(1000000 / frameTime));
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+ penY += dy;
+ sprintf (str, "Angle tol: %f", ctx->m_angle_tolerance);
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+ penY += dy;
+ sprintf (str, "Dist tol: %f", ctx->m_distance_tolerance);
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+ penY += dy;
+ sprintf (str, "Cups lim: %f", ctx->m_cusp_limit);
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+ penY += dy;
+ sprintf (str, "Recurs lim: %f", ctx->curve_recursion_limit);
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+ penY += dy;
+ sprintf (str, "Colinear €: %f", ctx->curve_collinearity_epsilon);
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+ penY += dy;
+ sprintf (str, "Angle tol €: %f", ctx->curve_angle_tolerance_epsilon);
+ vkvg_move_to(ctx,penX,penY);
+ vkvg_show_text(ctx, str);
+}
+
+double time_diff(struct timeval x , struct timeval y)
+{
+ double x_ms , y_ms , diff;
+
+ x_ms = (double)x.tv_sec*1000000 + (double)x.tv_usec;
+ y_ms = (double)y.tv_sec*1000000 + (double)y.tv_usec;
+
+ diff = (double)y_ms - (double)x_ms;
+
+ return diff;
+}
+void test_1 () {
+ const char* text = "This is a petit test {}";
+
+ VkvgContext ctx = vkvg_create (surf);
+
+ vkvg_set_source_rgba(ctx,0,0,0,1.0);
+ vkvg_paint (ctx);
+ vkvg_set_source_rgba(ctx,1,1,1,1.0);
+
+ vkvg_select_font_face(ctx, "mono");
+ vkvg_set_font_size(ctx, 12);
+
+ vkvg_font_extents_t f = {};
+ vkvg_font_extents(ctx, &f);
+
+ vkvg_text_extents_t t = {};
+ vkvg_text_extents(ctx, text, &t);
+
+ vkvg_move_to(ctx,100,100);
+ vkvg_show_text(ctx, text);
+
+ vkvg_move_to(ctx,100,100.5 - f.ascent);
+ vkvg_line_to(ctx,100+t.width,100.5 - f.ascent);
+
+ vkvg_move_to(ctx,100,100.5 - f.descent);
+ vkvg_line_to(ctx,100+t.width,100.5 - f.descent);
+
+ vkvg_stroke(ctx);
+
+ vkvg_flush(ctx);
+ vkvg_destroy (ctx);
+}
+void test_painting () {
+ VkvgSurface surf2 = vkvg_surface_create (device,400,400);;
+ VkvgContext ctx = vkvg_create (surf2);
+
+ vkvg_set_source_rgba(ctx,1.0,0.,0.,1.0);
+ vkvg_paint (ctx);
+
+ vkvg_destroy (ctx);
+ ctx = vkvg_create (surf);
+
+ vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0);
+ vkvg_paint (ctx);
+
+ //vkvg_set_source_surface(ctx,surf2,0,0);
+
+ //VkvgPattern pat = vkvg_get_source (ctx);
+ VkvgPattern pat = vkvg_pattern_create_for_surface(surf2);
+ vkvg_pattern_set_extend (pat,VKVG_EXTEND_REFLECT);
+ vkvg_set_source(ctx,pat);
+ //vkvg_paint (ctx);
+ //vkvg_set_source_rgba(ctx,0,1,0,1.0);
+ vkvg_rectangle(ctx,100,100,200,200);
+ vkvg_fill(ctx);
+
+ vkvg_destroy (ctx);
+ vkvg_surface_destroy (surf2);
+ vkvg_pattern_destroy (pat);
+}
+
+void simple_paint () {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,1,0,0,1);
+ vkvg_paint(ctx);
+ vkvg_destroy(ctx);
+}
+void simple_rectangle_fill () {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,0,1,0,1);
+ vkvg_rectangle(ctx,100,100,200,200);
+ vkvg_fill(ctx);
+ vkvg_destroy(ctx);
+}
+void simple_rectangle_stroke () {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgba(ctx,0,0,1,1);
+ vkvg_set_line_width(ctx,10.f);
+ vkvg_rectangle(ctx,100,100,200,200);
+ vkvg_stroke(ctx);
+ vkvg_destroy(ctx);
+}
+int main(int argc, char *argv[]) {
+
+ //dumpLayerExts();
+
+ vk_engine_t* e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, 1024, 800);
+ VkhPresenter r = e->renderer;
+ vkengine_set_key_callback (e, key_callback);
+
+ device = vkvg_device_create (r->dev->phy, r->dev->dev, r->qFam, 0);
+ surf = vkvg_surface_create(device, 1024, 800);
+
+ //test_svg();
+ //
+
+
+ //test_grad_transforms();
+ //cairo_tests();
+ //test_colinear();
+
+ vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf));
+
+ /*
+ while (!vkengine_should_close (e)) {
+ glfwPollEvents();
+ //test_1();
+ cairo_tests();
+ //simple_paint();
+ //simple_rectangle_stroke();
+ //simple_rectangle_fill();
+ //test_img_surface();
+ //multi_test1();
+ //test_painting();
+ if (!vkh_presenter_draw (r))
+ vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf));
+ }
+ */
+ struct timeval before , after;
+
+
+ while (!vkengine_should_close (e)) {
+
+
+ VkvgContext ctx = vkvg_create(surf);
+
+ gettimeofday(&before , NULL);
+
+ vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0);
+ vkvg_paint(ctx);
+
+ ctx->m_angle_tolerance = m_angle_tolerance;
+ ctx->m_distance_tolerance = m_distance_tolerance;
+ ctx->m_cusp_limit = m_cusp_limit;
+ ctx->curve_recursion_limit = curve_recursion_limit;
+ ctx->curve_angle_tolerance_epsilon = curve_angle_tolerance_epsilon;
+ ctx->curve_collinearity_epsilon = curve_collinearity_epsilon;
+
+ //vkvg_test_curves(ctx);
+ //vkvg_test_curves2(ctx);
+ test_svg(ctx);
+
+
+ print_float(ctx);
+
+ gettimeofday(&after , NULL);
+
+ vkvg_destroy(ctx);
+
+ glfwPollEvents();
+ if (!vkh_presenter_draw (r))
+ vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf));
+
+ frameTime = time_diff(before , after);
+ }
+
+ vkDeviceWaitIdle(e->dev->dev);
+
+ vkvg_surface_destroy (surf);
+ vkvg_device_destroy (device);
+
+ vkengine_destroy (e);
+
+ return 0;
+}