/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
 *            svgloader.cc
 *
 *  Mon May  1 11:03:39 CEST 2006
 *  Copyright  2006 Bent Bisballe Nyeng
 *  deva@aasimon.org
 ****************************************************************************/

/*
 *  This file is part of MIaV.
 *
 *  MIaV is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  MIaV is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MIaV; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */
#include "svgloader.h"

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

#include <cairo.h>
#include <svg.h>
#include <svg-cairo.h>

SVGLoader::SVGLoader()
{
}

SVGLoader::~SVGLoader()
{
}

/* load: This is what you're probably interested in!
 * -----------------------------------------------------
 *  If width and height are greater than 0, the image will
 *  be scaled to that size. wscale and hscale would be ignored.
 *
 *  If width and height are less than 1, wscale and hscale will
 *  resize the width and the height to the specified scales.
 *
 *  If width and height are less than 1, and wscale and hscale
 *  are either 0 or 1, then the image will be loaded at it's
 *  natural size.
 *
 *  See main() for examples.
 */
QImage SVGLoader::load(QString file, unsigned int width, unsigned int height, float wscale, float hscale) {
  svg_cairo_t *scr;
  int bpp;
  int btpp;
  unsigned int rwidth;
  unsigned int rheight;
  
  // Create the SVG cairo stuff. 
  svg_cairo_create(&scr);
  svg_cairo_parse(scr, file.toStdString().c_str());
  
  if (wscale <= 0) wscale=1;
  if (hscale <= 0) hscale=1;
  
  // Now get the width and height of the SVG content, so we can calculate 
  // and adjust our image dimensions
  svg_cairo_get_size (scr, &rwidth, &rheight);
  
  // Calculate final width and height of our surface based on the parameters passed
  if (width > 0) {
    if (rwidth>width) {
      wscale=(float)width/(float)rwidth;
      //      printf ("rwidth/width = %f\n", wscale);
    } else {
      wscale=(float)rwidth/(float)width;
      //      printf ("width/wwidth = %f\n", wscale);
    }
  } else {
    width=(int)(rwidth*wscale);
    //    printf ("width = %i\n", width);
  }
  if (height > 0) {
    if (rheight>height) {
      hscale=(float)height/(float)rheight;
      //      printf ("height/rheight = %f\n", hscale);
    } else {
      hscale=(float)rheight/(float)height;
      //      printf ("rheight/height = %f\n", hscale);
    }
  } else {
    height=(int)(rheight*hscale);
    //    printf ("height = %i\n", height);
  }
    
  // 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; // bits per pixel
  btpp=4; // bytes per pixel
  
  // scanline width
  int stride=width * btpp;
  
  // Allocate an image
  unsigned char *image=(unsigned char*)calloc(stride*height, 1);

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

  cairo_t *cr = cairo_create(cairo_surface);
  cairo_scale(cr, wscale, hscale);

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

  // Cleanup cairo
  cairo_surface_destroy(cairo_surface);
  cairo_destroy(cr);

  // Destroy the svg_cairo structure
  svg_cairo_destroy(scr);

  // Create the QImage using the render buffer.
  QImage qimage(image, width, height, QImage::Format_ARGB32);
  return qimage;
}