Converted icon renderer to use RSVG via C rather than pyrsvg
This commit is contained in:
parent
c12e134981
commit
c14ee293fe
4 changed files with 230 additions and 14 deletions
|
|
@ -22,3 +22,7 @@ vgsuppression_SOURCES = $(admin_srcdir)/vgsuppression.c
|
|||
vgsuppression_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
vgsuppression_LDADD = liblumi.a -lnobugmt -lpthread -ldl
|
||||
|
||||
noinst_PROGRAMS += rsvg-convert
|
||||
rsvg_convert_SOURCES = $(admin_srcdir)/rsvg-convert.c
|
||||
rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror
|
||||
rsvg_convert_LDADD = -lcairo -lglib-2.0 -lgthread-2.0 -lrsvg-2
|
||||
|
|
|
|||
|
|
@ -24,12 +24,11 @@ import getopt
|
|||
from xml.dom import minidom
|
||||
import os
|
||||
import shutil
|
||||
import cairo
|
||||
import rsvg
|
||||
|
||||
#svgDir = "svg"
|
||||
#prerenderedDir = "prerendered"
|
||||
inkscapePath = "/usr/bin/inkscape"
|
||||
rsvgPath = "./rsvg-convert"
|
||||
artworkLayerPrefix = "artwork:"
|
||||
|
||||
def createDirectory( name ):
|
||||
|
|
@ -105,18 +104,11 @@ def renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size):
|
|||
# Prepare a Cairo context
|
||||
width = int(rectangle[2])
|
||||
height = int(rectangle[3])
|
||||
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
||||
context = cairo.Context(surface)
|
||||
context.translate(-rectangle[0], -rectangle[1])
|
||||
|
||||
# Load an render the SVG
|
||||
svg = rsvg.Handle(file=file_path)
|
||||
svg.render_cairo(context)
|
||||
|
||||
# Output a PNG file
|
||||
surface.write_to_png(os.path.join(out_dir,
|
||||
"%ix%i/%s.png" % (width, height, artwork_name)))
|
||||
|
||||
os.spawnlp(os.P_WAIT, rsvgPath, rsvgPath,
|
||||
"--source-rect=%g:%g:%g:%g" % (rectangle[0], rectangle[1], rectangle[2], rectangle[3]),
|
||||
"--output=" + os.path.join(out_dir, "%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name)),
|
||||
file_path)
|
||||
|
||||
def renderSvgIcon(file_path, out_dir):
|
||||
artwork_name, doc_size, rectangles = parseSVG(file_path)
|
||||
|
|
|
|||
219
admin/rsvg-convert.c
Normal file
219
admin/rsvg-convert.c
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-
|
||||
|
||||
rsvg-convert.c: Command line utility for exercising rsvg with cairo.
|
||||
|
||||
Copyright (C) 2005 Red Hat, Inc.
|
||||
Copyright (C) 2005 Dom Lachowicz <cinamod@hotmail.com>
|
||||
Copyright (C) 2005 Caleb Moore <c.moore@student.unsw.edu.au>
|
||||
Copyright (C) 2008 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Authors: Carl Worth <cworth@cworth.org>,
|
||||
Caleb Moore <c.moore@student.unsw.edu.au>,
|
||||
Dom Lachowicz <cinamod@hotmail.com>,
|
||||
Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
*/
|
||||
|
||||
#ifndef N_
|
||||
#define N_(X) X
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <librsvg-2/librsvg/rsvg.h>
|
||||
#include <librsvg-2/librsvg/rsvg-cairo.h>
|
||||
|
||||
#ifdef CAIRO_HAS_PS_SURFACE
|
||||
#include <cairo-ps.h>
|
||||
#endif
|
||||
|
||||
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||
#include <cairo-pdf.h>
|
||||
#endif
|
||||
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
#define _(X) X
|
||||
#endif
|
||||
|
||||
struct RsvgSizeCallbackData {
|
||||
gint width;
|
||||
gint height;
|
||||
};
|
||||
|
||||
struct RsvgSourceRectangle {
|
||||
double left;
|
||||
double top;
|
||||
double width;
|
||||
double height;
|
||||
};
|
||||
|
||||
static void
|
||||
display_error (GError * err)
|
||||
{
|
||||
if (err) {
|
||||
g_print ("%s", err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rsvg_cairo_size_callback (int *width, int *height, gpointer data)
|
||||
{
|
||||
RsvgDimensionData *dimensions = data;
|
||||
*width = dimensions->width;
|
||||
*height = dimensions->height;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
rsvg_cairo_write_func (void *closure, const unsigned char *data, unsigned int length)
|
||||
{
|
||||
fwrite (data, 1, length, (FILE *) closure);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GOptionContext *g_option_context;
|
||||
int width = -1;
|
||||
int height = -1;
|
||||
char *source_rect_string = NULL;
|
||||
char *output = NULL;
|
||||
GError *error = NULL;
|
||||
char *filename = NULL;
|
||||
|
||||
char **args = NULL;
|
||||
RsvgHandle *rsvg;
|
||||
cairo_surface_t *surface = NULL;
|
||||
cairo_t *cr = NULL;
|
||||
RsvgDimensionData dimensions;
|
||||
FILE *output_file = stdout;
|
||||
|
||||
struct RsvgSourceRectangle source_rect = {0, 0, 0, 0};
|
||||
|
||||
GOptionEntry options_table[] = {
|
||||
{"width", 'w', 0, G_OPTION_ARG_INT, &width,
|
||||
N_("width [optional; defaults to the SVG's width]"), N_("<int>")},
|
||||
{"height", 'h', 0, G_OPTION_ARG_INT, &height,
|
||||
N_("height [optional; defaults to the SVG's height]"), N_("<int>")},
|
||||
{"source-rect", 'r', 0, G_OPTION_ARG_STRING, &source_rect_string,
|
||||
N_("source rectangle [optional; defaults to rectangle of the SVG document]"), N_("left:top:width:height")},
|
||||
{"output", 'o', 0, G_OPTION_ARG_STRING, &output,
|
||||
N_("output filename"), NULL},
|
||||
{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("FILE")},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
g_thread_init(NULL);
|
||||
|
||||
g_option_context = g_option_context_new (_("- SVG Converter"));
|
||||
g_option_context_add_main_entries (g_option_context, options_table, NULL);
|
||||
g_option_context_set_help_enabled (g_option_context, TRUE);
|
||||
if (!g_option_context_parse (g_option_context, &argc, &argv, &error)) {
|
||||
display_error (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (g_option_context);
|
||||
|
||||
if (output != NULL) {
|
||||
output_file = fopen (output, "wb");
|
||||
if (!output_file) {
|
||||
fprintf (stderr, _("Error saving to file: %s\n"), output);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (args[0] != NULL) {
|
||||
filename = args[0];
|
||||
}
|
||||
|
||||
/* Parse the source rect */
|
||||
if(source_rect_string != NULL) {
|
||||
const int n = sscanf(source_rect_string, "%lg:%lg:%lg:%lg",
|
||||
&source_rect.left, &source_rect.top,
|
||||
&source_rect.width, &source_rect.height);
|
||||
if(n != 4 || source_rect.width <= 0.0 || source_rect.height < 0.0) {
|
||||
fprintf (stderr, _("Invalid source rect: %s\n"), source_rect_string);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rsvg_init ();
|
||||
|
||||
rsvg = rsvg_handle_new_from_file (filename, &error);
|
||||
|
||||
if (!rsvg) {
|
||||
fprintf (stderr, _("Error reading SVG:"));
|
||||
display_error (error);
|
||||
fprintf (stderr, "\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* if the user did not specify a source rectangle, get the page size from the SVG */
|
||||
if(source_rect_string == NULL) {
|
||||
rsvg_handle_set_size_callback (rsvg, rsvg_cairo_size_callback, &dimensions, NULL);
|
||||
source_rect.left = 0;
|
||||
source_rect.top = 0;
|
||||
source_rect.width = dimensions.width;
|
||||
source_rect.height = dimensions.height;
|
||||
}
|
||||
|
||||
rsvg_handle_get_dimensions (rsvg, &dimensions);
|
||||
|
||||
if(width != -1 && height != -1) {
|
||||
dimensions.width = width;
|
||||
dimensions.height = height;
|
||||
} else if(source_rect_string != NULL) {
|
||||
dimensions.width = source_rect.width;
|
||||
dimensions.height = source_rect.height;
|
||||
}
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
dimensions.width, dimensions.height);
|
||||
|
||||
cr = cairo_create (surface);
|
||||
|
||||
cairo_translate(cr, -source_rect.left, -source_rect.top);
|
||||
|
||||
if(width != -1 && height != -1 && source_rect_string != NULL) {
|
||||
cairo_scale(cr, (double)dimensions.width / (double)source_rect.width,
|
||||
(double)dimensions.height / (double)source_rect.height);
|
||||
}
|
||||
|
||||
rsvg_handle_render_cairo (rsvg, cr);
|
||||
|
||||
cairo_surface_write_to_png_stream (surface, rsvg_cairo_write_func, output_file);
|
||||
|
||||
g_object_unref (G_OBJECT (rsvg));
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
fclose (output_file);
|
||||
|
||||
rsvg_term ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -33,6 +33,7 @@ iconcommand = python $(top_srcdir)/admin/render-icon.py
|
|||
48x48pre = $(prerendereddir)/48x48
|
||||
|
||||
lumigui_DEPENDENCIES += \
|
||||
rsvg-convert \
|
||||
$(16x16)/arrow.png $(22x22)/arrow.png $(24x24)/arrow.png $(32x32)/arrow.png $(48x48)/arrow.png \
|
||||
$(16x16)/i-beam.png $(22x22)/i-beam.png $(24x24)/i-beam.png $(32x32)/i-beam.png $(48x48)/i-beam.png \
|
||||
$(16x16)/assets-panel.png \
|
||||
|
|
|
|||
Loading…
Reference in a new issue