From: Jean-Philippe Bruyère Date: Wed, 1 May 2019 21:09:43 +0000 (+0200) Subject: add nsvg interface in main vkvg header X-Git-Tag: v0.1-alpha~81 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=980f7858013650d31981cd62bfa270dcd2e4dda2;p=jp%2Fvkvg.git add nsvg interface in main vkvg header --- diff --git a/include/vkvg.h b/include/vkvg.h index ec30504..4c84195 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -176,6 +176,7 @@ void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdp VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height); VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath); VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, const char* filePath); +VkvgSurface vkvg_surface_create_from_svg_fragment (VkvgDevice dev, char *fragment); VkvgSurface vkvg_surface_create_for_VkhImage(VkvgDevice dev, void* vkhImg); // VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, uint32_t width, uint32_t height); VkvgSurface vkvg_surface_reference (VkvgSurface surf); @@ -191,6 +192,16 @@ VkImage vkvg_surface_get_vkh_image (VkvgSurface surf); void vkvg_surface_write_to_png (VkvgSurface surf, const char* path); void vkvg_multisample_surface_resolve (VkvgSurface surf); +//nsvg interface for easy svg drawing +typedef struct NSVGimage NSVGimage; + +NSVGimage* nsvg_load_file (VkvgDevice dev, const char* filePath); +NSVGimage* nsvg_load (VkvgDevice dev, char* fragment); +void nsvg_destroy (NSVGimage* svg); +void nsvg_get_size (NSVGimage* svg, int* width, int* height); +void vkvg_render_svg (VkvgContext ctx, NSVGimage* svg); + + //mimic from cairo, to facilitate usage of vkvg as cairo vulkan backend typedef enum _vkvg_operator { VKVG_OPERATOR_CLEAR, diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 5f33fca..5f06996 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -26,6 +26,8 @@ #include "vkvg_pattern.h" #include "vkh_queue.h" +#include "nanosvg.h" + #ifdef DEBUG static vec2 debugLinePoints[1000]; static uint32_t dlpCount = 0; @@ -868,3 +870,57 @@ void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix){ void vkvg_get_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix){ memcpy (matrix, &ctx->pushConsts.mat, sizeof(vkvg_matrix_t)); } + +void vkvg_render_svg (VkvgContext ctx, NSVGimage* svg){ + NSVGshape* shape; + NSVGpath* path; + + vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); + + 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); + } + +} diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index e26dcf5..44060e8 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -86,7 +86,7 @@ typedef struct _vkvg_device_t{ VkDescriptorSetLayout dslSrc; /**< context source surface descriptors layout */ VkDescriptorSetLayout dslGrad; /**< context gradient descriptors layout */ - int hdpi, /**< only used for FreeType fonts */ + int hdpi, /**< only used for FreeType fonts and svg loading */ vdpi; VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */ diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index c985cbd..d0d0b94 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -321,7 +321,7 @@ VkvgSurface vkvg_surface_create_from_image (VkvgDevice dev, const char* filePath return surf; } -void svg_set_color (VkvgContext ctx, uint32_t c, float alpha) { +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; @@ -329,8 +329,7 @@ void svg_set_color (VkvgContext ctx, uint32_t c, float alpha) { vkvg_set_source_rgba(ctx,r,g,b,a*alpha); } -VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, const char* filePath) { - NSVGimage* svg = nsvgParseFromFile(filePath, "px", 96); +VkvgSurface _svg_load (VkvgDevice dev, NSVGimage* svg) { NSVGshape* shape; NSVGpath* path; @@ -344,56 +343,10 @@ VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, const char* filePath) _init_surface (surf); VkvgContext ctx = vkvg_create(surf); - vkvg_set_fill_rule(ctx, VKVG_FILL_RULE_EVEN_ODD); - - 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); - } + vkvg_render_svg(ctx, svg); + vkvg_destroy(ctx); nsvgDelete(svg); - vkvg_destroy(ctx); surf->references = 1; vkvg_device_reference (surf->dev); @@ -401,6 +354,26 @@ VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, const char* filePath) return surf; } +VkvgSurface vkvg_surface_create_from_svg (VkvgDevice dev, const char* filePath) { + return _svg_load(dev, nsvgParseFromFile(filePath, "px", dev->hdpi)); +} +VkvgSurface vkvg_surface_create_from_svg_fragment (VkvgDevice dev, char* fragment) { + return _svg_load(dev, nsvgParse(fragment, "px", dev->hdpi)); +} +NSVGimage* nsvg_load_file (VkvgDevice dev, const char* filePath) { + return nsvgParseFromFile(filePath, "px", dev->hdpi); +} +NSVGimage* nsvg_load (VkvgDevice dev, char* fragment) { + return nsvgParse (fragment, "px", dev->hdpi); +} +void nsvg_destroy (NSVGimage* svg) { + nsvgDelete(svg); +} +void nsvg_get_size (NSVGimage* svg, int* width, int* height) { + *width = (int)svg->width; + *height = (int)svg->height; +} + void vkvg_surface_destroy(VkvgSurface surf) { surf->references--; diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index 983b285..c3fe682 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -40,4 +40,5 @@ typedef struct _vkvg_surface_t { }vkvg_surface; void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect); +void _svg_set_color (VkvgContext ctx, uint32_t c, float alpha); #endif diff --git a/tests/svg.c b/tests/svg.c index 4d11899..5e1881e 100644 --- a/tests/svg.c +++ b/tests/svg.c @@ -4,7 +4,7 @@ #define NANOSVG_IMPLEMENTATION // Expands implementation #include "nanosvg.h" -void svg_set_color (VkvgContext ctx, uint32_t c, float alpha) { +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; @@ -13,12 +13,17 @@ void svg_set_color (VkvgContext ctx, uint32_t c, float alpha) { } static float rotation = 0.f; +//static const char* path = "/mnt/devel/crow-drm/Images/Icons/minimize.svg"; +static const char* path = "data/tiger.svg"; void test_svg_surface() { - VkvgSurface svgSurf = vkvg_surface_create_from_svg(device, "data/tiger.svg"); + VkvgSurface svgSurf = vkvg_surface_create_from_svg(device, path); VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgb(ctx,0,0,0); + vkvg_paint(ctx); + vkvg_set_source_surface(ctx, svgSurf, 0,0); vkvg_paint(ctx); @@ -26,6 +31,15 @@ void test_svg_surface() { vkvg_surface_destroy(svgSurf); } +void test_nsvg() { + NSVGimage* svg = nsvg_load_file(device, path); + VkvgContext ctx = vkvg_create(surf); + vkvg_scale(ctx,0.04f,0.04f); + vkvg_render_svg(ctx, svg); + vkvg_destroy(ctx); + nsvg_destroy(svg); +} + void test_svg () { rotation+=0.01f; @@ -60,7 +74,6 @@ void test_svg () { 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; @@ -79,10 +92,10 @@ void test_svg () { } if (shape->fill.type == NSVG_PAINT_COLOR) - svg_set_color(ctx, shape->fill.color, o); + _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); + _svg_set_color(ctx, g->stops[0].color, o); } if (shape->fill.type != NSVG_PAINT_NONE){ @@ -94,10 +107,10 @@ void test_svg () { } if (shape->stroke.type == NSVG_PAINT_COLOR) - svg_set_color(ctx, shape->stroke.color, o); + _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); + _svg_set_color(ctx, g->stops[0].color, o); } vkvg_stroke(ctx); @@ -111,6 +124,6 @@ void test_svg () { int main(int argc, char *argv[]) { - perform_test (test_svg_surface, 1024, 768); + perform_test (test_nsvg, 1024, 768); return 0; }