Jump to content
  • Advertisement
Sign in to follow this  
nifker

How can I draw a svg to a SDL_Surface with nanosvg?

This topic is 913 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im trying to draw a svg to a SDL_Surface with this library:

This is my current code:

extern void nsvg_drawSVGtoSDLSurface(const char *svg_file, SDL_Surface *surface){
    NSVGimage *image;
    NSVGrasterizer *rast;
    unsigned char *img;
    int w, h;
    image = nsvgParseFromFile(svg_file,"px", 96.0F);
    if(image == NULL){
        printf("Image not found.\n");
        goto failing;
    }
    w = (int)image->width;
    h = (int)image->height;
    rast = nsvgCreateRasterizer();
    if(rast == NULL){
          printf("Rasterizer could not be initialized.\n");
          goto failing;
    }
    img = malloc(w*h*4);
    if(img == NULL){
        printf("Image buffer could not be allocated.\n");
        goto failing;
    }
    nsvgRasterize(rast, image, 0, 0, 1, img, w, h, w*4);
    surface = SDL_CreateRGBSurfaceFrom(img, w , h, 32, 1920, 0, 0, 0, 0);
    if(surface == NULL){
           printf("Failed to create a surface: %s", SDL_GetError());
           goto failing;
    }
    SDL_LockSurface(surface);
    free(img);

    failing:
    nsvgDeleteRasterizer(rast);
    nsvgDelete(image);
}

Share this post


Link to post
Share on other sites
Advertisement

Write the 'img' buffer to a file and open it in some image editor that supports raw files or just in a hex editor to make sure it contains somewhat proper data. If it does then the problem is in getting it onto the SDL surface, and if it doesn't then the problem is in drawing the SVG. Either way you know where to investigate.

 

(Also, in this case you code seems to do absolutely nothing with the SDL surface.. you create it and lock it... and.. then just exit your function?  Probably some logic error there, maybe you want the surface to be a reference or have your function return a pointer to the new surface).

Edited by Erik Rufelt

Share this post


Link to post
Share on other sites

Was a senseless question. Anyway I removed the line that locked the sdlwindow. I tought it would fix it...

And how do I recognize if the written buffer contains proper data?

Edited by nifker

Share this post


Link to post
Share on other sites

this is currently my whole code which doesnt work - has anyone improvements for it?

#include <SDL2/SDL.h>
#include <SDL2/SDL_main.h>
#include <stdio.h>

#define NANOSVG_ALL_COLOR_KEYWORDS
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"
#include "main.h"

#define WIDTH 1280
#define HEIGTH 800

extern void drawSVGtoSDLSurface(const char *svg_file, SDL_Surface *surface, SDL_Renderer *renderer, SDL_Texture *texture){
    NSVGimage *image;
    NSVGrasterizer *rast;
    unsigned char *img;
    int w, h;
    image = nsvgParseFromFile(svg_file,"px", 96.0F);
    if(image == NULL){
        printf("Image not found.\n");
        goto failing;
    }
    w = (int)image->width;
    h = (int)image->height;
    rast = nsvgCreateRasterizer();
    if(rast == NULL){
          printf("Rasterizer could not be initialized.\n");
          goto failing;
    }
    img = malloc(w*h*4);
    if(img == NULL){
        printf("Image buffer could not be allocated.\n");
        goto failing;
    }
    nsvgRasterize(rast, image, 0, 0, 1, img, w, h, w*4);
    //surface = SDL_CreateRGBSurfaceFrom(img, w , h, 32, 1920, 0, 0, 0, 0);
    surface = img;
    texture = SDL_CreateTextureFromSurface(renderer, surface);
    if(surface == NULL){
           printf("Failed to create a surface: %s", SDL_GetError());
           goto failing;
    }
    free(img);
    SDL_FreeSurface(surface);
    failing:
    nsvgDeleteRasterizer(rast);
    nsvgDelete(image);
}

int main(int argc, char argv[]){
    if(SDL_Init(SDL_INIT_VIDEO) != 0){
        printf("Initialising SDL failed: %s", SDL_GetError());
        return -1;
    }
    SDL_Window *window;
    window=SDL_CreateWindow("WINDOW", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGTH, SDL_WINDOW_MAXIMIZED);
    if(window == NULL){
        printf("Couldn't create the window: %s", SDL_GetError());
        return -1;
    }
    SDL_Renderer *renderer;
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_Texture *tex;
    SDL_Surface *surf;
    drawSVGtoSDLSurface("../assets/textures/test.svg", surf, renderer, tex);
    while (1) {
        SDL_Event e;
        if (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                break;
            }
        }

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, tex, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyTexture(tex);
    SDL_Quit();
    return 0;
}

Share this post


Link to post
Share on other sites

Try doing SDL_Texture **texture in your method signature and then *texture = SDL_CreateTexture...

 

You should be studying pointers and how arguments are passed and returned from your functions and learn why that is. You have similar overwriting of a passed in argument in 'surface' that you don't even need to pass to the method. These are important underlying concepts that will come up in every function you write. Even if you can get this one to work by changing a few * around it's important to learn why or the next function you write will likely have the same problem.

Edited by Erik Rufelt

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!