2010-01-01 18:45:35 +00:00
|
|
|
/***************************************************************************
|
|
|
|
|
|
|
|
csvgimage.cpp
|
|
|
|
|
|
|
|
(c) 2004-2006 - Daniel Campos Fernández <dcamposf@gmail.com>
|
|
|
|
|
|
|
|
This program 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, or (at your option)
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
This program 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 this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#define __CSVGIMAGE_CPP
|
|
|
|
|
|
|
|
#include <cairo.h>
|
|
|
|
#include <cairo-svg.h>
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
#include "gambas.h"
|
|
|
|
#include "widgets.h"
|
|
|
|
#include "cpaint_impl.h"
|
|
|
|
#include "csvgimage.h"
|
|
|
|
|
2010-01-01 21:32:45 +00:00
|
|
|
#define MM_TO_PT(_mm) ((_mm) * 72 / 25.4)
|
2010-01-01 18:45:35 +00:00
|
|
|
#define PT_TO_MM(_pt) ((_pt) / 72 * 25.4)
|
|
|
|
|
2010-01-02 03:59:02 +00:00
|
|
|
static void release(CSVGIMAGE *_object)
|
2010-01-01 18:45:35 +00:00
|
|
|
{
|
2010-01-01 23:20:25 +00:00
|
|
|
if (HANDLE)
|
|
|
|
{
|
|
|
|
rsvg_handle_free(HANDLE);
|
|
|
|
HANDLE = NULL;
|
|
|
|
}
|
2010-01-02 01:55:03 +00:00
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
if (SURFACE)
|
|
|
|
{
|
|
|
|
cairo_surface_destroy(SURFACE);
|
|
|
|
THIS->surface = NULL;
|
|
|
|
unlink(THIS->file);
|
|
|
|
GB.FreeString(&THIS->file);
|
|
|
|
}
|
2010-01-02 01:55:03 +00:00
|
|
|
|
|
|
|
THIS->width = THIS->height = 0;
|
2010-01-01 18:45:35 +00:00
|
|
|
}
|
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
cairo_surface_t *SVGIMAGE_begin(CSVGIMAGE *_object)
|
2010-01-01 21:32:45 +00:00
|
|
|
{
|
|
|
|
if (!SURFACE)
|
|
|
|
{
|
|
|
|
if (THIS->width <= 0 || THIS->height <= 0)
|
2010-01-02 01:55:03 +00:00
|
|
|
{
|
|
|
|
GB.Error("SvgImage size is not defined");
|
2010-01-01 21:32:45 +00:00
|
|
|
return NULL;
|
2010-01-02 01:55:03 +00:00
|
|
|
}
|
2010-01-01 21:32:45 +00:00
|
|
|
|
2010-06-04 23:48:53 +00:00
|
|
|
THIS->file = GB.NewZeroString(GB.TempFile(NULL));
|
2010-01-02 01:55:03 +00:00
|
|
|
SURFACE = cairo_svg_surface_create(THIS->file, THIS->width, THIS->height);
|
|
|
|
|
|
|
|
if (HANDLE)
|
|
|
|
{
|
|
|
|
cairo_t *context = cairo_create(SURFACE);
|
|
|
|
rsvg_handle_render_cairo(HANDLE, context);
|
|
|
|
cairo_destroy(context);
|
|
|
|
}
|
2010-01-01 21:32:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return SURFACE;
|
|
|
|
}
|
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
void SVGIMAGE_end(CSVGIMAGE *_object)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-01-01 18:45:35 +00:00
|
|
|
BEGIN_METHOD(SvgImage_new, GB_FLOAT width; GB_FLOAT height)
|
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
THIS->width = VARGOPT(width, 0);
|
|
|
|
THIS->height = VARGOPT(height, 0);
|
2010-01-01 18:45:35 +00:00
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(SvgImage_free)
|
|
|
|
|
|
|
|
release(THIS);
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_PROPERTY(SvgImage_Width)
|
|
|
|
|
2010-01-01 21:32:45 +00:00
|
|
|
if (READ_PROPERTY)
|
2010-01-02 01:55:03 +00:00
|
|
|
GB.ReturnFloat(THIS->width);
|
2010-01-01 21:32:45 +00:00
|
|
|
else
|
2010-01-02 01:55:03 +00:00
|
|
|
THIS->width = VPROP(GB_FLOAT);
|
2010-01-01 18:45:35 +00:00
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
|
|
BEGIN_PROPERTY(SvgImage_Height)
|
2010-01-01 21:32:45 +00:00
|
|
|
|
|
|
|
if (READ_PROPERTY)
|
2010-01-02 01:55:03 +00:00
|
|
|
GB.ReturnFloat(THIS->height);
|
2010-01-01 21:32:45 +00:00
|
|
|
else
|
2010-01-02 01:55:03 +00:00
|
|
|
THIS->height = VPROP(GB_FLOAT);
|
2010-01-01 18:45:35 +00:00
|
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
|
2010-08-29 01:39:59 +00:00
|
|
|
static const char *load_file(CSVGIMAGE *_object, const char *path, int len_path)
|
2010-01-02 01:55:03 +00:00
|
|
|
{
|
2010-01-01 23:20:25 +00:00
|
|
|
RsvgHandle *handle = NULL;
|
2010-01-02 01:55:03 +00:00
|
|
|
RsvgDimensionData dim;
|
2010-01-01 23:20:25 +00:00
|
|
|
char *addr;
|
|
|
|
int len;
|
2010-08-29 01:39:59 +00:00
|
|
|
const char *err = NULL;
|
2010-01-01 23:20:25 +00:00
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
if (GB.LoadFile(path, len_path, &addr, &len))
|
2010-08-29 01:39:59 +00:00
|
|
|
return "Unable to load SVG file";
|
2010-01-01 23:20:25 +00:00
|
|
|
|
2010-01-03 17:09:57 +00:00
|
|
|
handle = rsvg_handle_new_from_data((const guint8 *)addr, len / sizeof(guint8), NULL);
|
2010-01-01 23:20:25 +00:00
|
|
|
if (!handle)
|
|
|
|
{
|
2010-08-29 01:39:59 +00:00
|
|
|
err = "Unable to load SVG file: invalid format";
|
2010-01-01 23:20:25 +00:00
|
|
|
goto __RETURN;
|
|
|
|
}
|
2010-01-02 01:55:03 +00:00
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
rsvg_handle_set_dpi(handle, 72);
|
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
release(THIS);
|
|
|
|
THIS->handle = handle;
|
|
|
|
rsvg_handle_get_dimensions(handle, &dim);
|
|
|
|
THIS->width = dim.width;
|
|
|
|
THIS->height = dim.height;
|
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
handle = NULL;
|
|
|
|
|
|
|
|
__RETURN:
|
|
|
|
|
|
|
|
if (handle)
|
|
|
|
rsvg_handle_free(handle);
|
|
|
|
|
2010-01-02 03:59:02 +00:00
|
|
|
GB.ReleaseFile(addr, len);
|
2010-08-29 01:39:59 +00:00
|
|
|
return err;
|
2010-01-02 01:55:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BEGIN_METHOD(SvgImage_Load, GB_STRING path)
|
|
|
|
|
|
|
|
CSVGIMAGE *svgimage;
|
2010-08-29 01:39:59 +00:00
|
|
|
const char *err;
|
2010-01-02 01:55:03 +00:00
|
|
|
|
|
|
|
GB.New(POINTER(&svgimage), CLASS_SvgImage, NULL, NULL);
|
|
|
|
|
2010-08-29 01:39:59 +00:00
|
|
|
if ((err = load_file(svgimage, STRING(path), LENGTH(path))))
|
2010-01-02 01:55:03 +00:00
|
|
|
{
|
|
|
|
GB.Unref(POINTER(&svgimage));
|
2010-08-29 01:39:59 +00:00
|
|
|
GB.Error(err);
|
2010-01-02 01:55:03 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-01-01 23:20:25 +00:00
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
GB.ReturnObject(svgimage);
|
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(SvgImage_Paint)
|
|
|
|
|
|
|
|
cairo_t *context = PAINT_get_current_context();
|
2010-08-29 01:39:59 +00:00
|
|
|
const char *err;
|
2010-01-01 23:20:25 +00:00
|
|
|
|
|
|
|
if (!context)
|
|
|
|
return;
|
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
if (THIS->file)
|
|
|
|
{
|
|
|
|
cairo_surface_finish(SURFACE);
|
2010-08-29 01:39:59 +00:00
|
|
|
if ((err = load_file(THIS, THIS->file, GB.StringLength(THIS->file))))
|
|
|
|
{
|
|
|
|
GB.Error(err);
|
|
|
|
return;
|
|
|
|
}
|
2010-01-02 01:55:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
if (!HANDLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
rsvg_handle_render_cairo(HANDLE, context);
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
BEGIN_METHOD(SvgImage_Save, GB_STRING file)
|
|
|
|
|
|
|
|
if (!THIS->file)
|
|
|
|
{
|
|
|
|
if (!SVGIMAGE_begin(THIS))
|
|
|
|
{
|
|
|
|
GB.Error("Void image");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cairo_surface_finish(SURFACE);
|
2010-01-02 03:59:02 +00:00
|
|
|
if (GB.CopyFile(THIS->file, GB.FileName(STRING(file), LENGTH(file))))
|
|
|
|
return;
|
|
|
|
|
2010-01-02 01:55:03 +00:00
|
|
|
load_file(THIS, THIS->file, GB.StringLength(THIS->file));
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
|
|
BEGIN_METHOD_VOID(SvgImage_Clear)
|
|
|
|
|
|
|
|
release(THIS);
|
|
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
2010-01-01 18:45:35 +00:00
|
|
|
GB_DESC SvgImageDesc[] =
|
|
|
|
{
|
|
|
|
GB_DECLARE("SvgImage", sizeof(CSVGIMAGE)),
|
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
GB_METHOD("_new", NULL, SvgImage_new, "[(Width)f(Height)f]"),
|
|
|
|
GB_METHOD("_free", NULL, SvgImage_free, NULL),
|
2010-01-01 18:45:35 +00:00
|
|
|
|
2010-01-01 21:32:45 +00:00
|
|
|
GB_PROPERTY("Width", "f", SvgImage_Width),
|
|
|
|
GB_PROPERTY("Height", "f", SvgImage_Height),
|
2010-01-01 18:45:35 +00:00
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
GB_STATIC_METHOD("Load", "SvgImage", SvgImage_Load, "(Path)s"),
|
|
|
|
GB_METHOD("Save", NULL, SvgImage_Save, "(Path)s"),
|
|
|
|
GB_METHOD("Paint", NULL, SvgImage_Paint, NULL),
|
2010-01-01 18:45:35 +00:00
|
|
|
|
2010-01-01 23:20:25 +00:00
|
|
|
GB_METHOD("Clear", NULL, SvgImage_Clear, NULL),
|
2010-01-01 18:45:35 +00:00
|
|
|
|
|
|
|
GB_INTERFACE("Paint", &PAINT_Interface),
|
|
|
|
|
|
|
|
GB_END_DECLARE
|
|
|
|
};
|
|
|
|
|