]> O.S.I.I.S - jp/vkvg.git/commitdiff
add nsvg interface in main vkvg header
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 1 May 2019 21:09:43 +0000 (23:09 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 1 May 2019 21:09:43 +0000 (23:09 +0200)
include/vkvg.h
src/vkvg_context.c
src/vkvg_device_internal.h
src/vkvg_surface.c
src/vkvg_surface_internal.h
tests/svg.c

index ec3050405cd8e00e51f64e1a29893ca233d42252..4c841952d0b5558a6c736b012bcd81b8ce268381 100644 (file)
@@ -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,
index 5f33fcae18b588a887886455026cc091a18cafb5..5f06996a233fac793e9769ea1a2165d33f90e720 100644 (file)
@@ -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);
+    }
+
+}
index e26dcf59f33c4de47d239a40c788d14b472cacd0..44060e87976b0d24c4d55c4905b87f38bfd2534e 100644 (file)
@@ -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 */
index c985cbd51d14ecdfc883b6ac19b5681e8105e3fe..d0d0b94714d81038d961841284b08d3a92f304a4 100644 (file)
@@ -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--;
index 983b285ecc0893e83b874d48c6e1bd5baa62692f..c3fe682380f446aba0c4b4d3aa06caa66bee7afc 100644 (file)
@@ -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
index 4d1189926aa88d2671dc105b26b0b7bc674745c2..5e1881ea016d3265da53733498ca5fe177571bae 100644 (file)
@@ -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;
 }