summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am26
-rw-r--r--librsvg.def1
-rw-r--r--test-display.c706
3 files changed, 281 insertions, 452 deletions
diff --git a/Makefile.am b/Makefile.am
index 5aca4aad..e53d5692 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,9 +11,6 @@ endif
lib_LTLIBRARIES = librsvg-@RSVG_API_MAJOR_VERSION@.la
bin_PROGRAMS = rsvg-convert
-if HAVE_GTK_2
-bin_PROGRAMS += rsvg-view
-endif
if HAVE_GTK_3
bin_PROGRAMS += rsvg-view-3
endif
@@ -130,29 +127,6 @@ rsvg_convert_LDADD = \
$(GTHREAD_LIBS) \
$(LIBM)
-rsvg_view_SOURCES = \
- test-display.c
-
-rsvg_view_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- -DLIBRSVG_DATADIR="\"$(datadir)\"" \
- $(AM_CPPFLAGS)
-
-rsvg_view_CFLAGS =\
- $(GTK2_CFLAGS) \
- $(LIBRSVG_CFLAGS) \
- $(AM_CFLAGS)
-
-rsvg_view_LDFLAGS =
-
-rsvg_view_LDADD = \
- $(top_builddir)/librsvg-@RSVG_API_MAJOR_VERSION@.la \
- $(GTK2_LIBS) \
- $(LIBRSVG_LIBS) \
- $(GTHREAD_LIBS) \
- $(LIBM)
-
rsvg_view_3_SOURCES = \
test-display.c
diff --git a/librsvg.def b/librsvg.def
index 37b30b3a..79373eee 100644
--- a/librsvg.def
+++ b/librsvg.def
@@ -35,7 +35,6 @@ rsvg_handle_render_cairo
rsvg_handle_render_cairo_sub
rsvg_handle_get_type
_rsvg_size_callback
-_rsvg_acquire_xlink_href_resource
_rsvg_register_types
rsvg_defs_lookup
rsvg_pixbuf_from_data_with_size_data
diff --git a/test-display.c b/test-display.c
index 0231ac03..a71ad0f7 100644
--- a/test-display.c
+++ b/test-display.c
@@ -30,147 +30,188 @@
#include <gtk/gtk.h>
#include <gdk/gdk.h>
-#if GTK_CHECK_VERSION(2,90,7)
-#define GDK_KEY(symbol) GDK_KEY_##symbol
-#else
-#include <gdk/gdkkeysyms.h>
-#define GDK_KEY(symbol) GDK_##symbol
+#if 0 // defined (G_OS_UNIX)
+#include <gio/gunixinputstream.h>
#endif
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 480
-static char *
-_rsvg_basename (const char *file)
-{
- if (file && *file)
- return g_path_get_basename (file);
+/* RsvgImage */
- return NULL;
-}
+#define RSVG_TYPE_IMAGE (rsvg_image_get_type ())
+#define RSVG_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RSVG_TYPE_IMAGE, RsvgImage))
-typedef struct _ViewerCbInfo ViewerCbInfo;
-struct _ViewerCbInfo {
- GtkWidget *window;
- GtkWidget *popup_menu;
- GtkWidget *image; /* the image widget */
+typedef struct _RsvgImage RsvgImage;
+typedef struct _RsvgImageClass RsvgImageClass;
- GdkPixbuf *pixbuf;
- GByteArray *svg_bytes;
- GtkAccelGroup *accel_group;
- char *base_uri;
- char *id;
- gdouble x_zoom;
- gdouble y_zoom;
+struct _RsvgImage {
+ GtkWidget parent_instance;
+
+ cairo_surface_t *surface; /* a cairo image surface */
};
-static gboolean
-get_image_size_from_data (ViewerCbInfo *info,
- gint *width,
- gint *height,
- GError **error)
+struct _RsvgImageClass {
+ GtkWidgetClass parent_class;
+};
+
+static GType rsvg_image_get_type (void);
+
+static void
+rsvg_image_take_surface (RsvgImage *image,
+ cairo_surface_t *surface)
{
- RsvgHandle *handle;
- RsvgDimensionData dimensions;
+ if (image->surface == surface)
+ return;
+ if (image->surface)
+ cairo_surface_destroy (image->surface);
+ image->surface = surface; /* adopted */
- handle = rsvg_handle_new ();
+ gtk_widget_queue_resize (GTK_WIDGET (image));
+}
- if (!handle) {
- g_set_error (error, rsvg_error_quark (), 0, _("Error creating SVG reader"));
- return FALSE;
- }
+G_DEFINE_TYPE (RsvgImage, rsvg_image, GTK_TYPE_WIDGET);
- rsvg_handle_set_base_uri (handle, info->base_uri);
+static void
+rsvg_image_init (RsvgImage *image)
+{
+ gtk_widget_set_has_window (GTK_WIDGET (image), FALSE);
+}
- if (!rsvg_handle_write (handle, info->svg_bytes->data, info->svg_bytes->len, error)) {
- g_object_unref (handle);
- return FALSE;
- }
+static void
+rsvg_image_finalize (GObject *object)
+{
+ RsvgImage *image = RSVG_IMAGE (object);
- if (!rsvg_handle_close (handle, error)) {
- g_object_unref (handle);
- return FALSE;
- }
+ rsvg_image_take_surface (image, NULL);
+}
+
+static void
+rsvg_image_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ RsvgImage *image = RSVG_IMAGE (widget);
- (void) rsvg_handle_get_dimensions_sub (handle, &dimensions, info->id);
- g_object_unref (handle);
+ *minimum = *natural = image->surface ? cairo_image_surface_get_width (image->surface) : 1;
+}
- if (width)
- *width = dimensions.width;
- if (height)
- *height = dimensions.height;
+static void
+rsvg_image_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ RsvgImage *image = RSVG_IMAGE (widget);
- return TRUE;
+ *minimum = *natural = image->surface ? cairo_image_surface_get_height (image->surface) : 1;
}
static gboolean
-calculate_zoom_ratio (ViewerCbInfo *info,
- struct RsvgSizeCallbackData *size_data,
- GError **error)
+rsvg_image_draw (GtkWidget *widget,
+ cairo_t *cr)
{
- GdkScreen *screen;
- gint image_width, image_height;
- gint screen_width, screen_height;
- gdouble x_zoom = 1.0, y_zoom = 1.0, zoom;
+ RsvgImage *image = RSVG_IMAGE (widget);
+
+ if (image->surface == NULL)
+ return FALSE;
- if (!get_image_size_from_data (info, &image_width, &image_height, error))
- return FALSE;
+ cairo_save (cr);
+ cairo_set_source_surface (cr, image->surface, 0, 0);
+ cairo_paint (cr);
+ cairo_restore (cr);
- screen = gdk_screen_get_default ();
- screen_width = gdk_screen_get_width (screen);
- screen_height = gdk_screen_get_height (screen);
+ return FALSE;
+}
- if (image_width > screen_width)
- x_zoom = (gdouble) screen_width / image_width * 0.8;
+static void
+rsvg_image_class_init (RsvgImageClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- if (image_height > screen_height)
- y_zoom = (gdouble) screen_height / image_height * 0.8;
+ gobject_class->finalize = rsvg_image_finalize;
+ widget_class->get_preferred_width = rsvg_image_get_preferred_width;
+ widget_class->get_preferred_height = rsvg_image_get_preferred_height;
+ widget_class->draw = rsvg_image_draw;
+}
- zoom = MAX (x_zoom, y_zoom);
+static RsvgImage *
+rsvg_image_new_take_surface (cairo_surface_t *surface)
+{
+ RsvgImage *image;
- info->x_zoom = zoom;
- info->y_zoom = zoom;
- size_data->x_zoom = zoom;
- size_data->y_zoom = zoom;
+ image = g_object_new (RSVG_TYPE_IMAGE, NULL);
+ rsvg_image_take_surface (image, surface);
- return TRUE;
+ return image;
}
-static GdkPixbuf *
-pixbuf_from_data_with_size_data (const guchar * buff,
- size_t len,
- struct RsvgSizeCallbackData *data,
- const char *base_uri,
- const char *id,
- GError ** error)
+static cairo_surface_t *
+rsvg_image_get_surface (RsvgImage *image)
{
- RsvgHandle *handle;
- GdkPixbuf *retval;
+ return image->surface;
+}
- handle = rsvg_handle_new ();
+/* Main */
- if (!handle) {
- g_set_error (error, rsvg_error_quark (), 0, _("Error creating SVG reader"));
- return NULL;
- }
+static char *
+_rsvg_basename (const char *file)
+{
+ if (file && *file)
+ return g_path_get_basename (file);
+
+ return NULL;
+}
- rsvg_handle_set_size_callback (handle, _rsvg_size_callback, data, NULL);
- rsvg_handle_set_base_uri (handle, base_uri);
+typedef struct _ViewerCbInfo ViewerCbInfo;
+struct _ViewerCbInfo {
+ GtkWidget *window;
+ GtkWidget *popup_menu;
+ RsvgImage *image;
+ RsvgHandle *handle;
+ GtkAccelGroup *accel_group;
+ char *base_uri;
+ char *id;
+ RsvgDimensionData dimensions;
+ gdouble x_zoom;
+ gdouble y_zoom;
+};
- if (!rsvg_handle_write (handle, buff, len, error)) {
- g_object_unref (handle);
+static cairo_surface_t *
+render_to_surface (ViewerCbInfo *info)
+{
+ RsvgDimensionData dimensions;
+ int width, height;
+ cairo_matrix_t matrix;
+ GdkPixbuf *output = NULL;
+ guint8 *pixels;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ int rowstride, minimum;
+
+ width = ceil ((double) info->dimensions.width * info->x_zoom);
+ height = ceil ((double) info->dimensions.height * info->y_zoom);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
+ cairo_surface_destroy (surface);
return NULL;
}
- if (!rsvg_handle_close (handle, error)) {
- g_object_unref (handle);
+ cr = cairo_create (surface);
+
+ cairo_matrix_init_scale (&matrix, info->x_zoom, info->y_zoom);
+ cairo_transform (cr, &matrix);
+
+ if (!rsvg_handle_render_cairo_sub (info->handle, cr, info->id)) {
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
return NULL;
}
- retval = rsvg_handle_get_pixbuf_sub (handle, id);
- g_object_unref (handle);
+ cairo_destroy (cr);
- return retval;
+ return surface;
}
static void
@@ -207,79 +248,26 @@ set_window_title (ViewerCbInfo * info)
static void
zoom_image (ViewerCbInfo * info, gdouble factor)
{
- struct RsvgSizeCallbackData size_data;
- GdkPixbuf *save_pixbuf = info->pixbuf;
-
info->x_zoom *= factor;
info->y_zoom *= factor;
- size_data.type = RSVG_SIZE_WH;
- size_data.width = gdk_pixbuf_get_width (info->pixbuf) * factor;
- size_data.height = gdk_pixbuf_get_height (info->pixbuf) * factor;
- size_data.keep_aspect_ratio = FALSE;
-
- info->pixbuf =
- pixbuf_from_data_with_size_data (info->svg_bytes->data, info->svg_bytes->len,
- &size_data, info->base_uri, info->id, NULL);
- gtk_image_set_from_pixbuf (GTK_IMAGE (info->image), info->pixbuf);
+ rsvg_image_take_surface (info->image, render_to_surface (info));
set_window_title (info);
-
- if (save_pixbuf)
- g_object_unref (save_pixbuf);
}
static void
zoom_in (GObject * ignored, ViewerCbInfo * info)
{
- if (!info->pixbuf)
- return;
- zoom_image (info, 1.25);
+ zoom_image (info, sqrt (G_SQRT2));
}
static void
zoom_out (GObject * ignored, ViewerCbInfo * info)
{
- if (!info->pixbuf)
- return;
- zoom_image (info, 1. / 1.25);
-}
-
-static void
-rsvg_window_set_default_icon (GtkWindow * window, GdkPixbuf * src)
-{
- GList *list;
- GdkPixbuf *icon;
- gint width, height;
-
- width = gdk_pixbuf_get_width (src);
- height = gdk_pixbuf_get_height (src);
-
- if (width > 128 || height > 128) {
- /* sending images greater than 128x128 has this nasty tendency to
- cause broken pipe errors X11 Servers */
- if (width > height) {
- width = 0.5 + width * 128. / height;
- height = 128;
- } else {
- height = 0.5 + height * 128. / width;
- width = 128;
- }
-
- icon = gdk_pixbuf_scale_simple (src, width, height, GDK_INTERP_BILINEAR);
- } else {
- icon = g_object_ref (src);
- }
-
- list = g_list_prepend (NULL, icon);
- gtk_window_set_icon_list (window, list);
- g_list_free (list);
-
- g_object_unref (icon);
+ zoom_image (info, 1. / sqrt (G_SQRT2));
}
-#if GTK_CHECK_VERSION(2,10,0)
-
static void
begin_print (GtkPrintOperation *operation,
GtkPrintContext *context,
@@ -295,48 +283,40 @@ draw_page (GtkPrintOperation *operation,
gpointer user_data)
{
ViewerCbInfo *info = (ViewerCbInfo *) user_data;
+ cairo_t *cr;
+ gdouble page_width, page_height, page_aspect;
+ gdouble width, height, aspect;
+ cairo_matrix_t matrix;
+
+ cr = gtk_print_context_get_cairo_context (context);
+ page_width = gtk_print_context_get_width (context);
+ page_height = gtk_print_context_get_height (context);
+ page_aspect = page_width / page_height;
+
+ // FIXMEchpe
+ rsvg_handle_set_dpi_x_y (info->handle,
+ gtk_print_context_get_dpi_x(context),
+ gtk_print_context_get_dpi_y(context));
+
+ width = info->dimensions.width;
+ height = info->dimensions.height;
+ aspect = width / height;
+
+ if (aspect <= page_aspect) {
+ width = page_height * aspect;
+ height = page_height;
+ } else {
+ width = page_width;
+ height = page_width / aspect;
+ }
- cairo_t *cr;
- gdouble page_width, page_height;
-
- cr = gtk_print_context_get_cairo_context (context);
- page_width = gtk_print_context_get_width (context);
- page_height = gtk_print_context_get_height (context);
-
- {
- RsvgHandle *handle;
- RsvgDimensionData svg_dimensions;
- struct RsvgSizeCallbackData size_data;
-
- /* should not fail */
- handle = rsvg_handle_new_from_data(info->svg_bytes->data, info->svg_bytes->len, NULL);
- rsvg_handle_set_base_uri (handle, info->base_uri);
- rsvg_handle_set_dpi_x_y (handle, gtk_print_context_get_dpi_x(context),
- gtk_print_context_get_dpi_y(context));
- rsvg_handle_get_dimensions(handle, &svg_dimensions);
-
- if (svg_dimensions.width > page_width || svg_dimensions.height > page_height) {
- /* scale down the image to the page's size, while preserving the aspect ratio */
-
- if ((double) svg_dimensions.height * (double) page_width > (double) svg_dimensions.width * (double) page_height) {
- svg_dimensions.width = 0.5 + (double) svg_dimensions.width *(double) page_height / (double) svg_dimensions.height;
- svg_dimensions.height = page_height;
- } else {
- svg_dimensions.height = 0.5 + (double) svg_dimensions.height *(double) page_width / (double) svg_dimensions.width;
- svg_dimensions.width = page_width;
- }
- }
-
- size_data.type = RSVG_SIZE_WH;
- size_data.width = svg_dimensions.width;
- size_data.height = svg_dimensions.height;
- size_data.keep_aspect_ratio = FALSE;
- rsvg_handle_set_size_callback (handle, _rsvg_size_callback, &size_data, NULL);
-
- rsvg_handle_render_cairo(handle, cr);
-
- g_object_unref (handle);
- }
+ cairo_save (cr);
+ cairo_matrix_init_scale (&matrix,
+ width / info->dimensions.width,
+ height / info->dimensions.height);
+ cairo_transform (cr, &matrix);
+ rsvg_handle_render_cairo (info->handle, cr);
+ cairo_restore (cr);
}
static void
@@ -356,8 +336,6 @@ print_pixbuf (GObject * ignored, gpointer user_data)
g_object_unref (print);
}
-#endif /* HAVE_GNOME_PRINT */
-
static char *
save_file (const char *title, const char *suggested_filename, GtkWidget * parent, int *success)
{
@@ -391,6 +369,7 @@ save_pixbuf (GObject * ignored, gpointer user_data)
ViewerCbInfo *info = (ViewerCbInfo *) user_data;
char *filename, *base_name, *filename_suggestion;
int success = 0;
+ cairo_surface_t *surface;
base_name = _rsvg_basename (info->base_uri);
if (base_name)
@@ -403,92 +382,18 @@ save_pixbuf (GObject * ignored, gpointer user_data)
g_free (filename_suggestion);
if (filename) {
- GError *err = NULL;
-
- if (!gdk_pixbuf_save (info->pixbuf, filename, "png", &err, NULL)) {
- if (err) {
+ surface = rsvg_image_get_surface (info->image);
+ if (cairo_surface_write_to_png (surface, filename) != CAIRO_STATUS_SUCCESS) {
GtkWidget *errmsg;
errmsg = gtk_message_dialog_new (GTK_WINDOW (info->window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CLOSE, "%s", err->message);
+ GTK_BUTTONS_CLOSE, "Failed to save");
gtk_dialog_run (GTK_DIALOG (errmsg));
- g_error_free (err);
gtk_widget_destroy (errmsg);
- }
- }
-
- g_free (filename);
- } else if (success) {
- GtkWidget *errmsg;
-
- errmsg = gtk_message_dialog_new (GTK_WINDOW (info->window),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CLOSE, _("No filename given"));
- gtk_window_set_transient_for (GTK_WINDOW (errmsg), GTK_WINDOW (info->window));
-
- gtk_dialog_run (GTK_DIALOG (errmsg));
- gtk_widget_destroy (errmsg);
- }
-}
-
-static void
-save_svg (GObject * ignored, gpointer user_data)
-{
- ViewerCbInfo *info = (ViewerCbInfo *) user_data;
- char *filename, *base_name;
- int success = 0;
-
- base_name = _rsvg_basename (info->base_uri);
- filename = save_file (_("Save SVG"), base_name, info->window, &success);
- g_free (base_name);
-
- if (filename) {
- FILE *fp;
-
- /* todo: make this support gnome vfs */
- fp = fopen (filename, "wb");
- if (!fp) {
- GtkWidget *errmsg;
-
- errmsg = gtk_message_dialog_new (GTK_WINDOW (info->window),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CLOSE, _("Couldn't save %s"), filename);
- gtk_window_set_transient_for (GTK_WINDOW (errmsg), GTK_WINDOW (info->window));
-
- gtk_dialog_run (GTK_DIALOG (errmsg));
- gtk_widget_destroy (errmsg);
- } else {
- size_t written = 0, remaining = info->svg_bytes->len;
- const unsigned char *buffer = info->svg_bytes->data;
-
- while (remaining > 0) {
- written = fwrite (buffer + (info->svg_bytes->len - remaining), 1, remaining, fp);
- if ((written < remaining) && ferror (fp) != 0) {
- GtkWidget *errmsg;
-
- errmsg = gtk_message_dialog_new (GTK_WINDOW (info->window),
- GTK_DIALOG_MODAL |
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
- _("Couldn't save %s"), filename);
- gtk_window_set_transient_for (GTK_WINDOW (errmsg), GTK_WINDOW (info->window));
-
- gtk_dialog_run (GTK_DIALOG (errmsg));
- gtk_widget_destroy (errmsg);
-
- break;
- }
-
- remaining -= written;
- }
-
- fclose (fp);
}
g_free (filename);
@@ -536,17 +441,10 @@ create_popup_menu (ViewerCbInfo * info)
g_signal_connect (menu_item, "activate", G_CALLBACK (copy_svg_location), info);
gtk_widget_show (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
- gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY(C),
+ gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY_C,
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
}
- menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE, NULL);
- g_signal_connect (menu_item, "activate", G_CALLBACK (save_svg), info);
- gtk_widget_show (menu_item);
- gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
- gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY(S), GDK_CONTROL_MASK,
- GTK_ACCEL_VISIBLE);
-
menu_item = gtk_image_menu_item_new_with_label (_("Save as PNG"));
stock = gtk_image_new_from_stock (GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_MENU);
gtk_widget_show (stock);
@@ -554,30 +452,28 @@ create_popup_menu (ViewerCbInfo * info)
g_signal_connect (menu_item, "activate", G_CALLBACK (save_pixbuf), info);
gtk_widget_show (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
- gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY(S),
+ gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY_S,
GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
-#if GTK_CHECK_VERSION(2,10,0)
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_PRINT, NULL);
g_signal_connect (menu_item, "activate", G_CALLBACK (print_pixbuf), info);
gtk_widget_show (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
- gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY(P), GDK_CONTROL_MASK,
+ gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY_P, GDK_CONTROL_MASK,
GTK_ACCEL_VISIBLE);
-#endif
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_ZOOM_IN, NULL);
g_signal_connect (menu_item, "activate", G_CALLBACK (zoom_in), info);
gtk_widget_show (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
- gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY(plus),
+ gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY_plus,
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_ZOOM_OUT, NULL);
g_signal_connect (menu_item, "activate", G_CALLBACK (zoom_out), info);
gtk_widget_show (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), menu_item);
- gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY(minus),
+ gtk_widget_add_accelerator (menu_item, "activate", info->accel_group, GDK_KEY_minus,
GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
info->popup_menu = popup_menu;
@@ -605,10 +501,17 @@ quit_cb (GtkWidget * win, gpointer unused)
}
static void
-populate_window (GtkWidget * win, ViewerCbInfo * info, int xid, gint win_width, gint win_height)
+populate_window (GtkWidget * win,
+ ViewerCbInfo * info,
+ cairo_surface_t *surface /* adopted */,
+ gint win_width,
+ gint win_height)
{
GtkWidget *vbox;
GtkWidget *scroll;
+ GtkWidget *toolbar;
+ GtkToolItem *toolitem;
+ GtkRequisition requisition;
gint img_width, img_height;
#if GTK_CHECK_VERSION (3, 2, 0)
@@ -618,56 +521,44 @@ populate_window (GtkWidget * win, ViewerCbInfo * info, int xid, gint win_width,
#endif
gtk_container_add (GTK_CONTAINER (win), vbox);
- /* create a new image */
- info->image = gtk_image_new_from_pixbuf (info->pixbuf);
-
/* pack the window with the image */
- img_width = gdk_pixbuf_get_width (info->pixbuf);
- img_height = gdk_pixbuf_get_height (info->pixbuf);
+ img_width = cairo_image_surface_get_width (surface);
+ img_height = cairo_image_surface_get_height (surface);
- if (xid <= 0) {
- GtkWidget *toolbar;
- GtkToolItem *toolitem;
- GtkRequisition requisition;
-
- toolbar = gtk_toolbar_new ();
- gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
+ /* create a new image */
+ info->image = rsvg_image_new_take_surface (surface);
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_IN);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, 0);
- g_signal_connect (toolitem, "clicked", G_CALLBACK (zoom_in), info);
+ toolbar = gtk_toolbar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_OUT);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, 1);
- g_signal_connect (toolitem, "clicked", G_CALLBACK (zoom_out), info);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_IN);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, 0);
+ g_signal_connect (toolitem, "clicked", G_CALLBACK (zoom_in), info);
- gtk_widget_size_request(toolbar, &requisition);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_OUT);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, 1);
+ g_signal_connect (toolitem, "clicked", G_CALLBACK (zoom_out), info);
- /* HACK: adjust for frame width & height + packing borders */
- img_height += requisition.height + 30;
- win_height += requisition.height + 30;
- img_width += 20;
- win_width += 20;
- }
+ gtk_widget_size_request(toolbar, &requisition);
- if ((xid > 0 && (img_width > win_width || img_height > win_height))
- || (xid <= 0)) {
- gtk_window_set_default_size (GTK_WINDOW (win), MIN (img_width, win_width),
- MIN (img_height, win_height));
+ /* HACK: adjust for frame width & height + packing borders */
+ img_height += requisition.height + 30;
+ win_height += requisition.height + 30;
+ img_width += 20;
+ win_width += 20;
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), info->image);
- gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
- } else {
- gtk_box_pack_start (GTK_BOX (vbox), info->image, TRUE, TRUE, 0);
- gtk_window_set_default_size (GTK_WINDOW (win), img_width, img_height);
- }
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll),
+ GTK_WIDGET (info->image));
+ gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
}
static void
-view_pixbuf (ViewerCbInfo * info, int xid, const char *color)
+view_surface (ViewerCbInfo * info,
+ cairo_surface_t *surface /* adopted */,
+ const char *color)
{
GtkWidget *win;
GdkColor bg_color;
@@ -680,9 +571,7 @@ view_pixbuf (ViewerCbInfo * info, int xid, const char *color)
win_width = DEFAULT_WIDTH;
win_height = DEFAULT_HEIGHT;
- populate_window (win, info, xid, win_width, win_height);
-
- rsvg_window_set_default_icon (GTK_WINDOW (win), info->pixbuf);
+ populate_window (win, info, surface, win_width, win_height);
/* exit when 'X' is clicked */
g_signal_connect (win, "destroy", G_CALLBACK (quit_cb), NULL);
@@ -690,17 +579,9 @@ view_pixbuf (ViewerCbInfo * info, int xid, const char *color)
if (color && strcmp (color, "none") != 0) {
if (gdk_color_parse (color, &bg_color)) {
- GtkWidget *parent_widget = gtk_widget_get_parent (info->image);
+ GtkWidget *parent_widget = gtk_widget_get_parent (GTK_WIDGET (info->image));
-#if GTK_CHECK_VERSION (2, 90, 8)
gtk_widget_modify_bg (parent_widget, GTK_STATE_NORMAL, &bg_color);
-#else
- if (gdk_colormap_alloc_color
- (gtk_widget_get_colormap (parent_widget), &bg_color, FALSE, TRUE))
- gtk_widget_modify_bg (parent_widget, GTK_STATE_NORMAL, &bg_color);
- else
- g_warning (_("Couldn't allocate color '%s'"), color);
-#endif
} else
g_warning (_("Couldn't parse color '%s'"), color);
}
@@ -732,10 +613,12 @@ main (int argc, char **argv)
int bVersion = 0;
char *bg_color = NULL;
char *base_uri = NULL;
- int bKeepAspect = 0;
+ gboolean keep_aspect_ratio = FALSE;
char *id = NULL;
+ GInputStream *input;
+ GFile *file, *base_file;
+ cairo_surface_t *surface;
- int xid = -1;
int from_stdin = 0;
ViewerCbInfo info;
@@ -763,7 +646,7 @@ main (int argc, char **argv)
N_("<string>")},
{"id", 0, 0, G_OPTION_ARG_STRING, &id, N_("Only show one node (default: all)"),
N_("<string>")},
- {"keep-aspect", 'k', 0, G_OPTION_ARG_NONE, &bKeepAspect,
+ {"keep-aspect", 'k', 0, G_OPTION_ARG_NONE, &keep_aspect_ratio,
N_("Preserve the image's aspect ratio"), NULL},
{"version", 'v', 0, G_OPTION_ARG_NONE, &bVersion, N_("Show version information"), NULL},
{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("[FILE...]")},
@@ -775,8 +658,6 @@ main (int argc, char **argv)
g_type_init ();
- info.pixbuf = NULL;
- info.svg_bytes = NULL;
info.window = NULL;
info.popup_menu = NULL;
@@ -795,10 +676,10 @@ main (int argc, char **argv)
return 0;
}
- if (args) {
- while (args[n_args] != NULL)
- n_args++;
- }
+ if (args)
+ n_args = g_strv_length (args);
+ else
+ n_args = 0;
if ((!from_stdin) && (n_args != 1)) {
g_print (_("No files specified, and not using --stdin\n"));
@@ -807,94 +688,70 @@ main (int argc, char **argv)
rsvg_set_default_dpi_x_y (dpi_x, dpi_y);
- /* if both are unspecified, assume user wants to zoom the pixbuf in at least 1 dimension */
- if (width == -1 && height == -1) {
- size_data.type = RSVG_SIZE_ZOOM;
- size_data.x_zoom = x_zoom;
- size_data.y_zoom = y_zoom;
- }
- /* if both are unspecified, assume user wants to resize pixbuf in at least 1 dimension */
- else if (x_zoom == 1.0 && y_zoom == 1.0) {
- size_data.type = RSVG_SIZE_WH;
- size_data.width = width;
- size_data.height = height;
- }
- /* assume the user wants to zoom the pixbuf, but cap the maximum size */
- else {
- size_data.type = RSVG_SIZE_ZOOM_MAX;
- size_data.x_zoom = x_zoom;
- size_data.y_zoom = y_zoom;
- size_data.width = width;
- size_data.height = height;
- }
-
- size_data.keep_aspect_ratio = bKeepAspect;
-
- if (!from_stdin) {
- if (base_uri == NULL)
- base_uri = (char *) args[0];
-
- info.svg_bytes = _rsvg_acquire_xlink_href_resource (args[0], base_uri, NULL);
+ if (from_stdin) {
+#if 0 // defined (G_OS_UNIX)
+ input = g_unix_input_stream_new (STDIN_FILENO, FALSE);
+#else
+ input = NULL;
+ g_set_error_literal (&err, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Reading from stdin not supported");
+#endif
+ base_file = NULL;
} else {
- info.svg_bytes = g_byte_array_new ();
+ file = g_file_new_for_commandline_arg (args[0]);
+ input = (GInputStream *) g_file_read (file, NULL, &err);
- for (;;) {
- unsigned char buf[1024 * 8];
- size_t nread = fread (buf, 1, sizeof (buf), stdin);
+ if (base_uri)
+ base_file = g_file_new_for_uri (base_uri);
+ else
+ base_file = g_object_ref (file);
- if (nread > 0)
- g_byte_array_append (info.svg_bytes, buf, nread);
-
- if (nread < sizeof (buf)) {
- if (ferror (stdin)) {
- g_print (_("Error reading\n"));
- g_byte_array_free (info.svg_bytes, TRUE);
- fclose (stdin);
-
- return 1;
- } else if (feof (stdin))
- break;
- }
- }
-
- fclose (stdin);
+ g_object_unref (file);
}
- if (!info.svg_bytes || !info.svg_bytes->len) {
- g_print (_("Couldn't open %s\n"), args[0]);
+ g_strfreev (args);
+
+ if (input == NULL) {
+ g_printerr ("Failed to read input: %s\n", err->message);
+ g_error_free (err);
return 1;
}
- info.base_uri = base_uri;
+ info.base_uri = base_file ? g_file_get_uri (base_file) : g_strdup ("");
info.id = id;
info.x_zoom = x_zoom;
info.y_zoom = y_zoom;
- if (size_data.type == RSVG_SIZE_ZOOM &&
- x_zoom == 1.0 && y_zoom == 1.0) {
- if (!calculate_zoom_ratio (&info, &size_data, &err)) {
- if (err) {
- g_print (": %s\n", err->message);
- g_error_free (err);
- }
- return 1;
- }
+ info.handle = rsvg_handle_new_from_stream_sync (input,
+ base_file,
+ RSVG_HANDLE_FLAGS_NONE,
+ NULL /* cancellable */,
+ &err);
+ g_object_unref (base_file);
+
+ if (info.handle == NULL) {
+ g_printerr ("Failed to load SVG: %s\n", err->message);
+ g_error_free (err);
+ g_object_unref (info.handle);
+ return 1;
}
- info.pixbuf =
- pixbuf_from_data_with_size_data (info.svg_bytes->data, info.svg_bytes->len, &size_data,
- base_uri, id, &err);
+ rsvg_handle_get_dimensions (info.handle, &info.dimensions);
- if (!info.pixbuf) {
- g_print (_("Error displaying image"));
-
- if (err) {
- g_print (": %s", err->message);
- g_error_free (err);
- }
-
- g_print ("\n");
+ if (width != -1) {
+ info.x_zoom = (double) width / info.dimensions.width;
+ } else {
+ info.x_zoom = x_zoom;
+ }
+ if (height != -1) {
+ info.y_zoom = (double) height / info.dimensions.height;
+ } else {
+ info.y_zoom = y_zoom;
+ }
+ surface = render_to_surface (&info);
+ if (surface == NULL) {
+ g_printerr (_("Error displaying image"));
goto done;
}
@@ -902,16 +759,15 @@ main (int argc, char **argv)
info.accel_group = gtk_accel_group_new ();
- view_pixbuf (&info, xid, bg_color);
+ view_surface (&info, surface, bg_color);
/* run the gtk+ main loop */
gtk_main ();
- g_object_unref (info.pixbuf);
-
done:
- g_byte_array_free (info.svg_bytes, TRUE);
- g_strfreev (args);
+
+ g_free (info.base_uri);
+ g_object_unref (info.handle);
rsvg_cleanup ();