gimp/plug-ins/common/file-svg.c

804 lines
28 KiB
C
Raw Permalink Normal View History

/* GIMP - The GNU Image Manipulation Program
2002-10-08 10:45:37 +08:00
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
2002-10-08 10:45:37 +08:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
2002-10-08 10:45:37 +08:00
* (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, see <https://www.gnu.org/licenses/>.
2002-10-08 10:45:37 +08:00
*/
/* SVG loader plug-in
* (C) Copyright 2003 Dom Lachowicz <cinamod@hotmail.com>
2003-03-19 00:21:30 +08:00
*
* Largely rewritten in September 2003 by Sven Neumann <sven@gimp.org>
2002-10-08 10:45:37 +08:00
*/
#include "config.h"
#include <stdlib.h>
2002-10-08 10:45:37 +08:00
#include <string.h>
#include <librsvg/rsvg.h>
2002-10-08 10:45:37 +08:00
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"
#include "libgimp/stdplugins-intl.h"
#define LOAD_PROC "file-svg-load"
#define PLUG_IN_BINARY "file-svg"
#define PLUG_IN_ROLE "gimp-file-svg"
#define SVG_VERSION "2.5.0"
#define SVG_DEFAULT_RESOLUTION 90.0
#define SVG_DEFAULT_SIZE 500
#define SVG_PREVIEW_SIZE 128
typedef struct
{
gdouble resolution;
gint width;
gint height;
} SvgLoadVals;
2019-08-19 05:47:03 +08:00
typedef struct _Svg Svg;
typedef struct _SvgClass SvgClass;
struct _Svg
{
2019-08-19 05:47:03 +08:00
GimpPlugIn parent_instance;
};
struct _SvgClass
{
GimpPlugInClass parent_class;
};
2019-08-19 05:47:03 +08:00
#define SVG_TYPE (svg_get_type ())
#define SVG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SVG_TYPE, Svg))
2019-08-19 05:47:03 +08:00
GType svg_get_type (void) G_GNUC_CONST;
static GList * svg_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * svg_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
static GimpUnit * svg_rsvg_to_gimp_unit (RsvgUnit unit);
static gboolean svg_extract (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
GimpMetadata *metadata,
GimpProcedureConfig *config,
GimpVectorLoadData *extracted_dimensions,
gpointer *data_for_run,
GDestroyNotify *data_for_run_destroy,
gpointer extract_data,
GError **error);
static GimpValueArray * svg_load (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
gint width,
gint height,
GimpVectorLoadData extracted_data,
GimpMetadata *metadata,
GimpMetadataLoadFlags *flags,
GimpProcedureConfig *config,
gpointer data_from_extract,
gpointer run_data);
static GimpImage * load_image (GFile *file,
RsvgHandle *handle,
gint width,
gint height,
gdouble resolution,
GError **error);
static GdkPixbuf * load_rsvg_pixbuf (RsvgHandle *handle,
gint width,
gint height,
gdouble resolution,
GError **error);
static GimpPDBStatusType load_dialog (GFile *file,
RsvgHandle *handle,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GimpVectorLoadData extracted_data,
GError **error);
static void svg_destroy_surface (guchar *pixels,
cairo_surface_t *surface);
2019-08-19 05:47:03 +08:00
G_DEFINE_TYPE (Svg, svg, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (SVG_TYPE)
DEFINE_STD_SET_I18N
2019-08-19 05:47:03 +08:00
2002-10-08 10:45:37 +08:00
static void
2019-08-19 05:47:03 +08:00
svg_class_init (SvgClass *klass)
2002-10-08 10:45:37 +08:00
{
2019-08-19 05:47:03 +08:00
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
2019-08-19 05:47:03 +08:00
plug_in_class->query_procedures = svg_query_procedures;
plug_in_class->create_procedure = svg_create_procedure;
plug_in_class->set_i18n = STD_SET_I18N;
2002-10-08 10:45:37 +08:00
}
static void
2019-08-19 05:47:03 +08:00
svg_init (Svg *svg)
2002-10-08 10:45:37 +08:00
{
2019-08-19 05:47:03 +08:00
}
2002-10-08 10:45:37 +08:00
2019-08-19 05:47:03 +08:00
static GList *
svg_query_procedures (GimpPlugIn *plug_in)
{
GList *list = NULL;
list = g_list_append (list, g_strdup (LOAD_PROC));
2002-10-08 10:45:37 +08:00
2019-08-19 05:47:03 +08:00
return list;
}
2002-10-08 10:45:37 +08:00
2019-08-19 05:47:03 +08:00
static GimpProcedure *
svg_create_procedure (GimpPlugIn *plug_in,
const gchar *name)
{
GimpProcedure *procedure = NULL;
2002-10-08 10:45:37 +08:00
2019-08-19 05:47:03 +08:00
if (! strcmp (name, LOAD_PROC))
2002-10-08 10:45:37 +08:00
{
procedure = gimp_vector_load_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_PLUGIN,
svg_extract, NULL, NULL,
svg_load, NULL, NULL);
2019-08-19 05:47:03 +08:00
gimp_procedure_set_menu_label (procedure, _("SVG image"));
2019-08-19 05:47:03 +08:00
gimp_procedure_set_documentation (procedure,
"Loads files in the SVG file format",
"Renders SVG files to raster graphics "
"using librsvg.",
name);
gimp_procedure_set_attribution (procedure,
"Dom Lachowicz, Sven Neumann",
"Dom Lachowicz <cinamod@hotmail.com>",
SVG_VERSION);
gimp_file_procedure_set_format_name (GIMP_FILE_PROCEDURE (procedure),
_("SVG"));
2019-08-19 05:47:03 +08:00
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
"image/svg+xml");
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"svg");
gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
"0,string,<?xml,0,string,<svg");
gimp_procedure_add_choice_argument (procedure, "paths",
_("_Paths"),
_("Whether and how to import paths so that they can be used with the path tool"),
gimp_choice_new_with_values ("no-import", 0, _("Don't import paths"), NULL,
"import", 0, _("Import paths individually"), NULL,
"import-merged", 0, _("Merge imported paths"), NULL,
NULL),
"no-import", G_PARAM_READWRITE);
2019-08-19 05:47:03 +08:00
}
return procedure;
}
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
static GimpUnit *
svg_rsvg_to_gimp_unit (RsvgUnit unit)
{
switch (unit)
2019-08-19 05:47:03 +08:00
{
case RSVG_UNIT_PERCENT:
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
return gimp_unit_percent ();
case RSVG_UNIT_PX:
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
return gimp_unit_pixel ();
case RSVG_UNIT_IN:
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
return gimp_unit_inch ();
case RSVG_UNIT_MM:
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
return gimp_unit_mm ();
case RSVG_UNIT_PT:
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
return gimp_unit_point ();
case RSVG_UNIT_PC:
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
return gimp_unit_pica ();
case RSVG_UNIT_CM:
case RSVG_UNIT_EM:
case RSVG_UNIT_EX:
/*case RSVG_UNIT_CH:*/
default:
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
return NULL;
}
}
2019-08-19 05:47:03 +08:00
static gboolean
svg_extract (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
GimpMetadata *metadata,
GimpProcedureConfig *config,
GimpVectorLoadData *extracted_dimensions,
gpointer *data_for_run,
GDestroyNotify *data_for_run_destroy,
gpointer extract_data,
GError **error)
{
RsvgHandle *handle;
#if LIBRSVG_CHECK_VERSION(2, 46, 0)
gboolean out_has_width;
RsvgLength out_width;
gboolean out_has_height;
RsvgLength out_height;
gboolean out_has_viewbox;
RsvgRectangle out_viewbox;
#endif
#if ! LIBRSVG_CHECK_VERSION(2, 52, 0)
RsvgDimensionData dim;
#endif
g_return_val_if_fail (extracted_dimensions != NULL, FALSE);
g_return_val_if_fail (data_for_run_destroy != NULL && *data_for_run_destroy == NULL, FALSE);
g_return_val_if_fail (data_for_run != NULL && *data_for_run == NULL, FALSE);
g_return_val_if_fail (error != NULL && *error == NULL, FALSE);
handle = rsvg_handle_new_from_gfile_sync (file, RSVG_HANDLE_FLAGS_NONE, NULL, error);
if (! handle)
{
if (run_mode == GIMP_RUN_INTERACTIVE)
{
GtkWidget *dialog;
GtkWidget *main_hbox;
GtkWidget *label;
gchar *text;
gboolean retry;
/* We need to ask explicitly before using the "unlimited" size
* option (XML_PARSE_HUGE in libxml) because it is considered
* unsafe, possibly consumming too much memory with malicious XML
* files.
*/
dialog = gimp_dialog_new (_("Disable safety size limits?"),
PLUG_IN_ROLE,
NULL, 0,
gimp_standard_help_func, LOAD_PROC,
_("_No"), GTK_RESPONSE_NO,
_("_Yes"), GTK_RESPONSE_YES,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO);
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
gimp_window_set_transient (GTK_WINDOW (dialog));
main_hbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
main_hbox, TRUE, TRUE, 0);
gtk_widget_show (main_hbox);
/* Unfortunately the error returned by librsvg is unclear. While
* libxml explicitly returns a "parser error : internal error:
* Huge input lookup", librsvg does not seem to relay this error.
* It sends a further parsing error, false positive provoked by
* the huge input error.
* If we were able to single out the huge data error, we could
* just directly return from the plug-in as a failure run in other
* cases. Instead of this, we need to ask each and every time, in
* case it might be the huge data error.
*/
label = gtk_label_new (_("A parsing error occurred.\n"
"Disabling safety limits may help. "
"Malicious SVG files may use this to consume too much memory."));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD);
gtk_label_set_max_width_chars (GTK_LABEL (label), 80);
gtk_box_pack_start (GTK_BOX (main_hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
label = gtk_label_new (NULL);
text = g_strdup_printf ("<b>%s</b>",
_("For security reasons, this should only be used for trusted input!"));
gtk_label_set_markup (GTK_LABEL (label), text);
g_free (text);
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start (GTK_BOX (main_hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
label = gtk_label_new (_("Retry without limits preventing to parse huge data?"));
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
gtk_box_pack_start (GTK_BOX (main_hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_widget_show (dialog);
retry = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_YES);
gtk_widget_destroy (dialog);
if (retry)
{
g_clear_error (error);
handle = rsvg_handle_new_from_gfile_sync (file, RSVG_HANDLE_FLAG_UNLIMITED, NULL, error);
}
}
if (! handle)
return FALSE;
2019-08-19 05:47:03 +08:00
}
2002-10-08 10:45:37 +08:00
/* SVG has no pixel density information */
extracted_dimensions->exact_density = TRUE;
extracted_dimensions->correct_ratio = TRUE;
#if LIBRSVG_CHECK_VERSION(2, 46, 0)
rsvg_handle_get_intrinsic_dimensions (handle,
&out_has_width, &out_width,
&out_has_height, &out_height,
&out_has_viewbox, &out_viewbox);
if (out_has_width && out_has_height)
{
/* "width" and "height" present: the viewbox has no importance (it's only
* a coordinate remapping.
*/
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
if (svg_rsvg_to_gimp_unit (out_width.unit) != NULL &&
svg_rsvg_to_gimp_unit (out_height.unit) != NULL)
{
/* Best case scenario: we know all these units. */
extracted_dimensions->width = out_width.length;
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
extracted_dimensions->width_unit = svg_rsvg_to_gimp_unit (out_width.unit);
extracted_dimensions->height = out_height.length;
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
extracted_dimensions->height_unit = svg_rsvg_to_gimp_unit (out_height.unit);
extracted_dimensions->exact_width = TRUE;
extracted_dimensions->exact_height = TRUE;
}
else
{
/* Ideally we let GIMP handle the transformation, but for cases where
* we don't know how, we let rsvg make a computation to pixel for us.
*/
#if LIBRSVG_CHECK_VERSION(2, 52, 0)
if (rsvg_handle_get_intrinsic_size_in_pixels (handle,
&extracted_dimensions->width,
&extracted_dimensions->height))
{
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
extracted_dimensions->width_unit = gimp_unit_pixel ();
extracted_dimensions->height_unit = gimp_unit_pixel ();
extracted_dimensions->exact_width = FALSE;
extracted_dimensions->exact_height = FALSE;
}
else
{
/* Honestly at this point, setting 300 PPI is random. */
rsvg_handle_set_dpi (handle, 300.0);
if (rsvg_handle_get_intrinsic_size_in_pixels (handle,
&extracted_dimensions->width,
&extracted_dimensions->height))
{
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
extracted_dimensions->width_unit = gimp_unit_percent ();
extracted_dimensions->height_unit = gimp_unit_percent ();
}
else if (out_width.unit == out_height.unit)
{
/* Odd case which should likely never happen as we have width,
* height and a (fake) pixel density. Just in case though.
*/
extracted_dimensions->width = out_width.length;
extracted_dimensions->height = out_height.length;
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
extracted_dimensions->width_unit = gimp_unit_percent ();
extracted_dimensions->height_unit = gimp_unit_percent ();
}
else
{
/* Should even less happen! */
return FALSE;
}
}
#else
rsvg_handle_get_dimensions (handle, &dim);
extracted_dimensions->width = (gdouble) dim.width;
extracted_dimensions->height = (gdouble) dim.height;
extracted_dimensions->exact_width = FALSE;
extracted_dimensions->exact_height = FALSE;
extracted_dimensions->correct_ratio = TRUE;
#endif
}
}
else if (out_has_viewbox)
{
/* Only a viewbox, so dimensions have a ratio, but no units. */
extracted_dimensions->width = out_width.length;
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
extracted_dimensions->width_unit = gimp_unit_percent ();
extracted_dimensions->exact_width = FALSE;
extracted_dimensions->height = out_height.length;
Issue #8900 and #9923: reimplementing GimpUnit as a proper class. This fixes all our GObject Introspection issues with GimpUnit which was both an enum and an int-derived type of user-defined units *completing* the enum values. GIR clearly didn't like this! Now GimpUnit is a proper class and units are unique objects, allowing to compare them with an identity test (i.e. `unit == gimp_unit_pixel ()` tells us if unit is the pixel unit or not), which makes it easy to use, just like with int, yet adding also methods, making for nicer introspected API. As an aside, this also fixes #10738, by having all the built-in units retrievable even if libgimpbase had not been properly initialized with gimp_base_init(). I haven't checked in details how GIR works to introspect, but it looks like it loads the library to inspect and runs functions, hence triggering some CRITICALS because virtual methods (supposed to be initialized with gimp_base_init() run by libgimp) are not set. This new code won't trigger any critical because the vtable method are now not necessary, at least for all built-in units. Note that GimpUnit is still in libgimpbase. It could have been moved to libgimp in order to avoid any virtual method table (since we need to keep core and libgimp side's units in sync, PDB is required), but too many libgimpwidgets widgets were already using GimpUnit. And technically most of GimpUnit logic doesn't require PDB (only the creation/sync part). This is one of the reasons why user-created GimpUnit list is handled and stored differently from other types of objects. Globally this simplifies the code a lot too and we don't need separate implementations of various utils for core and libgimp, which means less prone to errors.
2024-07-26 02:55:21 +08:00
extracted_dimensions->height_unit = gimp_unit_percent ();
extracted_dimensions->exact_height = FALSE;
extracted_dimensions->correct_ratio = TRUE;
}
else
{
/* Neither width nor viewbox. Nothing can be determined. */
return FALSE;
}
#else
rsvg_handle_get_dimensions (handle, &dim);
extracted_dimensions->width = (gdouble) dim.width;
extracted_dimensions->height = (gdouble) dim.height;
extracted_dimensions->exact_width = FALSE;
extracted_dimensions->exact_height = FALSE;
extracted_dimensions->correct_ratio = TRUE;
#endif
*data_for_run = handle;
*data_for_run_destroy = g_object_unref;
return TRUE;
2019-08-19 05:47:03 +08:00
}
2002-10-08 10:45:37 +08:00
2019-08-19 05:47:03 +08:00
static GimpValueArray *
svg_load (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
gint width,
gint height,
GimpVectorLoadData extracted_data,
GimpMetadata *metadata,
GimpMetadataLoadFlags *flags,
GimpProcedureConfig *config,
gpointer data_from_extract,
gpointer run_data)
2019-08-19 05:47:03 +08:00
{
GimpValueArray *return_vals;
GimpImage *image;
GError *error = NULL;
GimpPDBStatusType status;
gchar *import_paths;
gdouble resolution;
2019-08-19 05:47:03 +08:00
gegl_init (NULL, NULL);
if (run_mode == GIMP_RUN_INTERACTIVE)
{
status = load_dialog (file, RSVG_HANDLE (data_from_extract),
procedure, config, extracted_data, &error);
if (status != GIMP_PDB_SUCCESS)
return gimp_procedure_new_return_values (procedure, status, error);
}
2019-08-19 05:47:03 +08:00
g_object_get (config,
"width", &width,
"height", &height,
"pixel-density", &resolution,
NULL);
image = load_image (file, RSVG_HANDLE (data_from_extract),
width, height, resolution, &error);
2019-08-19 05:47:03 +08:00
if (! image)
2019-08-19 05:47:03 +08:00
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
error);
g_object_get (config, "paths", &import_paths, NULL);
if (g_strcmp0 (import_paths, "no-import") != 0)
{
GimpPath **paths;
gint num_paths;
gimp_image_import_paths_from_file (image, file,
g_strcmp0 (import_paths, "import-merged") == 0,
TRUE, &num_paths, &paths);
if (num_paths > 0)
g_free (paths);
}
g_free (import_paths);
2019-08-19 05:47:03 +08:00
return_vals = gimp_procedure_new_return_values (procedure,
GIMP_PDB_SUCCESS,
NULL);
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
2019-08-19 05:47:03 +08:00
return return_vals;
}
static GimpImage *
load_image (GFile *file,
RsvgHandle *handle,
gint width,
gint height,
gdouble resolution,
GError **load_error)
{
GimpImage *image;
GimpLayer *layer;
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = load_rsvg_pixbuf (handle, width, height, resolution, &error);
if (! pixbuf)
{
/* Do not rely on librsvg setting GError on failure! */
g_set_error (load_error,
error ? error->domain : 0, error ? error->code : 0,
_("Could not open '%s' for reading: %s"),
gimp_file_get_utf8_name (file),
error ? error->message : _("Unknown reason"));
g_clear_error (&error);
return NULL;
}
gimp_progress_init (_("Rendering SVG"));
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
image = gimp_image_new (width, height, GIMP_RGB);
gimp_image_undo_disable (image);
gimp_image_set_resolution (image, resolution, resolution);
layer = gimp_layer_new_from_pixbuf (image, _("Rendered SVG"), pixbuf,
100,
gimp_image_get_default_new_layer_mode (image),
0.0, 1.0);
gimp_image_insert_layer (image, layer, NULL, 0);
gimp_image_undo_enable (image);
return image;
}
#if ! LIBRSVG_CHECK_VERSION(2, 46, 0)
/* XXX Why we keep old deprecated implementation next to newer librsvg API is
* because librsvg uses Rust since version 2.41.0. There are 2 raised problems:
* 1. Rust is still not available or well tested on every architecture/OS out
* there yet so unless we decide to have SVG support as optional again, it
* would make GIMP non-available on these.
* 2. There are some technical-ideological position against Rust for bundling
* and linking dependencies statically.
* While the second point may or may not be a problem we want to take into
* account (I guess that it mostly depends on the amount of additional
* maintenance work it would imply), the first is definitely enough of a reason
* to keep an old version requirement.
* See also report #6821.
*/
static void
load_set_size_callback (gint *width,
gint *height,
gpointer data)
{
SvgLoadVals *vals = data;
if (*width < 1 || *height < 1)
{
*width = SVG_DEFAULT_SIZE;
*height = SVG_DEFAULT_SIZE;
}
if (!vals->width || !vals->height)
return;
/* either both arguments negative or none */
if ((vals->width * vals->height) < 0)
return;
if (vals->width > 0)
{
*width = vals->width;
*height = vals->height;
}
else
{
gdouble w = *width;
gdouble h = *height;
gdouble aspect = (gdouble) vals->width / (gdouble) vals->height;
if (aspect > (w / h))
{
*height = abs (vals->height);
*width = (gdouble) abs (vals->width) * (w / h) + 0.5;
}
else
{
*width = abs (vals->width);
*height = (gdouble) abs (vals->height) / (w / h) + 0.5;
}
vals->width = *width;
vals->height = *height;
}
}
#endif /* ! LIBRSVG_CHECK_VERSION(2, 46, 0) */
/* This function renders a pixbuf from an SVG file according to vals. */
static GdkPixbuf *
load_rsvg_pixbuf (RsvgHandle *handle,
gint width,
gint height,
gdouble resolution,
GError **error)
{
GdkPixbuf *pixbuf = NULL;
#if LIBRSVG_CHECK_VERSION(2, 46, 0)
cairo_surface_t *surface = NULL;
cairo_t *cr = NULL;
RsvgRectangle viewport = { 0, };
guchar *src;
gint y;
#else
SvgLoadVals vals;
#endif
g_return_val_if_fail (handle, NULL);
rsvg_handle_set_dpi (handle, resolution);
#if LIBRSVG_CHECK_VERSION(2, 46, 0)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
cr = cairo_create (surface);
viewport.width = width;
viewport.height = height;
rsvg_handle_render_document (handle, cr, &viewport, NULL);
pixbuf = gdk_pixbuf_new_from_data (cairo_image_surface_get_data (surface),
GDK_COLORSPACE_RGB, TRUE, 8, width, height,
cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width),
(GdkPixbufDestroyNotify) svg_destroy_surface, surface);
cairo_destroy (cr);
/* un-premultiply the data */
src = gdk_pixbuf_get_pixels (pixbuf);
for (y = 0; y < height; y++)
{
guchar *s = src;
gint w = width;
while (w--)
{
GIMP_CAIRO_ARGB32_GET_PIXEL (s, s[0], s[1], s[2], s[3]);
s += 4;
}
src += gdk_pixbuf_get_rowstride (pixbuf);
}
#else
vals.resolution = resolution;
vals.width = width;
vals.height = height;
rsvg_handle_set_size_callback (handle, load_set_size_callback, vals, NULL);
pixbuf = rsvg_handle_get_pixbuf (handle);
#endif
return pixbuf;
}
/* User interface */
static GimpSizeEntry *size = NULL;
static GtkAdjustment *xadj = NULL;
static GtkAdjustment *yadj = NULL;
static GtkWidget *constrain = NULL;
static gdouble ratio_x = 1.0;
static gdouble ratio_y = 1.0;
static gint svg_width = 0;
static gint svg_height = 0;
static void load_dialog_set_ratio (gdouble x,
gdouble y);
static void
load_dialog_size_callback (GtkWidget *widget,
gpointer data)
{
if (gimp_chain_button_get_active (GIMP_CHAIN_BUTTON (constrain)))
{
gdouble x = gimp_size_entry_get_refval (size, 0) / (gdouble) svg_width;
gdouble y = gimp_size_entry_get_refval (size, 1) / (gdouble) svg_height;
if (x != ratio_x)
{
load_dialog_set_ratio (x, x);
}
else if (y != ratio_y)
{
load_dialog_set_ratio (y, y);
}
}
}
static void
load_dialog_ratio_callback (GtkAdjustment *adj,
gpointer data)
{
gdouble x = gtk_adjustment_get_value (xadj);
gdouble y = gtk_adjustment_get_value (yadj);
if (gimp_chain_button_get_active (GIMP_CHAIN_BUTTON (constrain)))
{
if (x != ratio_x)
y = x;
else
x = y;
}
load_dialog_set_ratio (x, y);
}
static void
load_dialog_set_ratio (gdouble x,
gdouble y)
{
ratio_x = x;
ratio_y = y;
g_signal_handlers_block_by_func (size, load_dialog_size_callback, NULL);
gimp_size_entry_set_refval (size, 0, svg_width * x);
gimp_size_entry_set_refval (size, 1, svg_height * y);
g_signal_handlers_unblock_by_func (size, load_dialog_size_callback, NULL);
g_signal_handlers_block_by_func (xadj, load_dialog_ratio_callback, NULL);
g_signal_handlers_block_by_func (yadj, load_dialog_ratio_callback, NULL);
gtk_adjustment_set_value (xadj, x);
gtk_adjustment_set_value (yadj, y);
g_signal_handlers_unblock_by_func (xadj, load_dialog_ratio_callback, NULL);
g_signal_handlers_unblock_by_func (yadj, load_dialog_ratio_callback, NULL);
}
static GimpPDBStatusType
load_dialog (GFile *file,
RsvgHandle *handle,
GimpProcedure *procedure,
GimpProcedureConfig *config,
GimpVectorLoadData extracted_data,
GError **load_error)
{
GtkWidget *dialog;
gboolean run;
gimp_ui_init (PLUG_IN_BINARY);
dialog = gimp_vector_load_procedure_dialog_new (GIMP_VECTOR_LOAD_PROCEDURE (procedure),
GIMP_PROCEDURE_CONFIG (config),
&extracted_data, file);
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), NULL);
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gtk_widget_destroy (dialog);
return run ? GIMP_PDB_SUCCESS : GIMP_PDB_CANCEL;
}
static void
svg_destroy_surface (guchar *pixels,
cairo_surface_t *surface)
{
cairo_surface_destroy (surface);
}