// Based on cairo-demo/sdl/main.c from Cairo (GPL'd, (c) 2004 Eric Windisch):
SDL_Surface * load_svg(char * file)
{
  svg_cairo_t * scr;
  int bpp, btpp, stride;
  unsigned int width, height;
  unsigned int rwidth, rheight;
  float scale;
  unsigned char * image;
  cairo_surface_t * cairo_surface;
  cairo_t * cr;
  SDL_Surface * sdl_surface, * sdl_surface_tmp;
  Uint32 rmask, gmask, bmask, amask;
  svg_cairo_status_t res;


#ifdef DEBUG
  printf("Attempting to load \"%s\" as an SVG\n", file);
#endif

  // Create the SVG cairo stuff:
  if (svg_cairo_create(&scr) != SVG_CAIRO_STATUS_SUCCESS)
  {
#ifdef DEBUG
    printf("svg_cairo_create() failed\n");
#endif
    return(NULL);
  }

  // Parse the SVG file:
  if (svg_cairo_parse(scr, file) != SVG_CAIRO_STATUS_SUCCESS)
  {
    svg_cairo_destroy(scr);
#ifdef DEBUG
    printf("svg_cairo_parse(%s) failed\n", file);
#endif
    return(NULL);
  }

  // Get the natural size of the SVG
  svg_cairo_get_size(scr, &rwidth, &rheight);
#ifdef DEBUG
  printf("svg_get_size(): %d x %d\n", rwidth, rheight);
#endif

  if (rwidth == 0 || rheight == 0)
  {
    svg_cairo_destroy(scr);
#ifdef DEBUG
    printf("SVG %s had 0 width or height!\n", file);
#endif
    return(NULL);
  }

  // We will create a CAIRO_FORMAT_ARGB32 surface. We don't need to match
  // the screen SDL format, but we are interested in the alpha bit...
  bpp = 32;
  btpp = 4;

  // We want to render at full Tux Paint canvas size, so that the stamp
  // at its largest scale remains highest quality (no pixelization):
  // (but not messing up the aspect ratio)

  scale = pick_best_scape(rwidth, rheight, r_canvas.w, r_canvas.h);

  width = ((float) rwidth * scale);
  height = ((float) rheight * scale);

#ifdef DEBUG
  printf("scaling to %d x %d (%f scale)\n", width, height, scale);
#endif

  // scanline width
  stride = width * btpp;

  // Allocate space for an image:
  image = calloc(stride * height, 1);

#ifdef DEBUG
  printf("calling cairo_image_surface_create_for_data(..., CAIRO_FORMAT_ARGB32, %d(w), %d(h), %d(stride))\n", width, height, stride);
#endif

  // Create the cairo surface with the adjusted width and height
  cairo_surface = cairo_image_surface_create_for_data(image,
                                                      CAIRO_FORMAT_ARGB32,
                                                      width, height, stride);

  cr = cairo_create(cairo_surface);
  if (cr == NULL)
  {
    svg_cairo_destroy(scr);
#ifdef DEBUG
    printf("cairo_create() failed\n");
#endif
    return(NULL);
  }

  // Scale it (proportionally)
  cairo_scale(cr, scale, scale);  // no return value :(

  // Render SVG to our surface:
  res = svg_cairo_render(scr, cr);

  // Clean up:
  cairo_surface_destroy(cairo_surface);
  cairo_destroy(cr);
  svg_cairo_destroy(scr);

  if (res != SVG_CAIRO_STATUS_SUCCESS)
  {
#ifdef DEBUG
    printf("svg_cairo_render() failed\n");
#endif
    return(NULL);
  }


  // Adjust the SDL surface to match the cairo surface created
  // (surface mask of ARGB)  NOTE: Is this endian-agnostic? -bjk 2006.10.25
  rmask = 0x00ff0000;
  gmask = 0x0000ff00;
  bmask = 0x000000ff;
  amask = 0xff000000;

  // Create the SDL surface using the pixel data stored:
  sdl_surface_tmp = SDL_CreateRGBSurfaceFrom((void *) image, width, height,
                                             bpp, stride,
                                             rmask, gmask, bmask, amask);

  if (sdl_surface_tmp == NULL)
  {
#ifdef DEBUG
    printf("SDL_CreateRGBSurfaceFrom() failed\n");
#endif
    return(NULL);
  }


  // Convert the SDL surface to the display format, for faster blitting:
  sdl_surface = SDL_DisplayFormatAlpha(sdl_surface_tmp);
  SDL_FreeSurface(sdl_surface_tmp);

  if (sdl_surface == NULL)
  {
#ifdef DEBUG
    printf("SDL_DisplayFormatAlpha() failed\n");
#endif
    return(NULL);
  }

#ifdef DEBUG
  printf("SDL surface from %d x %d SVG is %d x %d\n",
	  rwidth, rheight, sdl_surface->w, sdl_surface->h);
#endif

  return(sdl_surface);
}

