optionally scale the imported SVG to fit the image.

2003-09-25  Sven Neumann  <sven@gimp.org>

	* app/vectors/gimpvectors-import.[ch]: optionally scale the
	imported SVG to fit the image.

	* app/gui/vectors-commands.c: changed accordingly.

	* tools/pdbgen/pdb/paths.pdb: export the new scale parameter to
	the PDB.

	* app/pdb/paths_cmds.c
	* libgimp/gimppaths_pdb.[ch]: regenerated.

	* plug-ins/common/svg.c: scale the imported vectors to image size.
	This makes them always fit :)
This commit is contained in:
Sven Neumann 2003-09-25 00:39:46 +00:00 committed by Sven Neumann
parent dc441cc925
commit b2ad956b0f
10 changed files with 118 additions and 43 deletions

View File

@ -1,3 +1,19 @@
2003-09-25 Sven Neumann <sven@gimp.org>
* app/vectors/gimpvectors-import.[ch]: optionally scale the
imported SVG to fit the image.
* app/gui/vectors-commands.c: changed accordingly.
* tools/pdbgen/pdb/paths.pdb: export the new scale parameter to
the PDB.
* app/pdb/paths_cmds.c
* libgimp/gimppaths_pdb.[ch]: regenerated.
* plug-ins/common/svg.c: scale the imported vectors to image size.
This makes them always fit :)
2003-09-24 Maurits Rijk <lpeek.mrijk@consunet.nl>
* plug-ins/common/illusion.c: applied rest of patch from

View File

@ -613,7 +613,7 @@ vectors_import_ok_callback (GtkWidget *widget)
filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (widget));
if (gimp_vectors_import (gimage, filename, FALSE, &error))
if (gimp_vectors_import (gimage, filename, FALSE, FALSE, &error))
{
gimp_image_flush (gimage);
}
@ -655,6 +655,9 @@ vectors_import_query (GimpImage *gimage)
G_CALLBACK (gtk_widget_destroy),
filesel);
/* FIXME: add a proper file selector
and controls for merge and scale options */
gtk_widget_show (GTK_WIDGET (filesel));
}

View File

@ -613,7 +613,7 @@ vectors_import_ok_callback (GtkWidget *widget)
filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (widget));
if (gimp_vectors_import (gimage, filename, FALSE, &error))
if (gimp_vectors_import (gimage, filename, FALSE, FALSE, &error))
{
gimp_image_flush (gimage);
}
@ -655,6 +655,9 @@ vectors_import_query (GimpImage *gimage)
G_CALLBACK (gtk_widget_destroy),
filesel);
/* FIXME: add a proper file selector
and controls for merge and scale options */
gtk_widget_show (GTK_WIDGET (filesel));
}

View File

@ -1205,6 +1205,7 @@ path_import_invoker (Gimp *gimp,
GimpImage *gimage;
gchar *filename;
gboolean merge;
gboolean scale;
gimage = gimp_image_get_by_ID (gimp, args[0].value.pdb_int);
if (! GIMP_IS_IMAGE (gimage))
@ -1216,8 +1217,10 @@ path_import_invoker (Gimp *gimp,
merge = args[2].value.pdb_int ? TRUE : FALSE;
scale = args[3].value.pdb_int ? TRUE : FALSE;
if (success)
success = gimp_vectors_import (gimage, filename, merge, NULL);
success = gimp_vectors_import (gimage, filename, merge, scale, NULL);
return procedural_db_return_args (&path_import_proc, success);
}
@ -1238,6 +1241,11 @@ static ProcArg path_import_inargs[] =
GIMP_PDB_INT32,
"merge",
"Merge paths into a single vectors object"
},
{
GIMP_PDB_INT32,
"scale",
"Scale the SVG to image dimensions"
}
};
@ -1250,7 +1258,7 @@ static ProcRecord path_import_proc =
"Sven Neumann",
"2003",
GIMP_INTERNAL,
3,
4,
path_import_inargs,
0,
NULL,

View File

@ -57,6 +57,7 @@ typedef struct
{
GQueue *stack;
GimpImage *image;
gboolean scale;
} SvgParser;
typedef struct _SvgHandler SvgHandler;
@ -143,8 +144,8 @@ static GList * parse_path_data (const gchar *data);
* gimp_vectors_import:
* @image: the #GimpImage to add the paths to
* @filename: name of a SVG file
* @merge: if multiple paths should be merged into a single #GimpVectors
* object
* @merge: should multiple paths be merged into a single #GimpVectors object
* @scale: should the SVG be scaled to fit the image dimensions
* @error: location to store possible errors
*
* Imports one or more paths from a SVG file.
@ -155,6 +156,7 @@ gboolean
gimp_vectors_import (GimpImage *image,
const gchar *filename,
gboolean merge,
gboolean scale,
GError **error)
{
GimpXmlParser *xml_parser;
@ -169,6 +171,7 @@ gimp_vectors_import (GimpImage *image,
parser.stack = g_queue_new ();
parser.image = image;
parser.scale = scale;
/* the base of the stack, defines the size of the view-port */
base = g_new0 (SvgHandler, 1);
@ -258,12 +261,12 @@ gimp_vectors_import (GimpImage *image,
}
static void
svg_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
svg_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
SvgParser *parser = user_data;
SvgHandler *handler;
@ -295,10 +298,10 @@ svg_parser_start_element (GMarkupParseContext *context,
}
static void
svg_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
svg_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
{
SvgParser *parser = user_data;
SvgHandler *handler;
@ -341,6 +344,7 @@ svg_handler_svg (SvgHandler *handler,
const gchar **values,
SvgParser *parser)
{
SvgHandler *base;
GimpMatrix3 *matrix;
GimpMatrix3 box;
const gchar *viewbox = NULL;
@ -389,12 +393,17 @@ svg_handler_svg (SvgHandler *handler,
values++;
}
#ifdef DEBUG_VECTORS_IMPORT
g_printerr ("%s; %g x %g (scale %g %g)\n", handler->id,
w, h, xscale, yscale);
#endif
gimp_matrix3_scale (matrix, xscale, yscale);
base = g_queue_peek_head (parser->stack);
if (x || y)
{
SvgHandler *base = g_queue_peek_head (parser->stack);
/* according to the spec offsets are meaningless on the outermost svg */
if (strcmp (base->name, "image"))
gimp_matrix3_translate (matrix, x, y);
@ -405,6 +414,15 @@ svg_handler_svg (SvgHandler *handler,
gimp_matrix3_mult (&box, matrix);
}
/* optionally scale the outermost svg to image size */
if (parser->scale && strcmp (base->name, "image") == 0)
{
if (w > 0.0 && h > 0.0)
gimp_matrix3_scale (matrix, base->width / w, base->height / h);
parser->scale = FALSE;
}
handler->width = w;
handler->height = h;
@ -424,7 +442,22 @@ svg_handler_group (SvgHandler *handler,
GimpMatrix3 matrix;
if (parse_svg_transform (*values, &matrix))
handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
{
handler->transform = g_memdup (&matrix, sizeof (GimpMatrix3));
#ifdef DEBUG_VECTORS_IMPORT
g_printerr ("%s: %g %g %g %g %g %g %g %g %g\n", handler->id,
handler->transform->coeff[0][0],
handler->transform->coeff[0][1],
handler->transform->coeff[0][2],
handler->transform->coeff[1][0],
handler->transform->coeff[1][1],
handler->transform->coeff[1][2],
handler->transform->coeff[2][0],
handler->transform->coeff[2][1],
handler->transform->coeff[2][2]);
#endif
}
}
names++;
@ -550,8 +583,7 @@ parse_svg_length (const gchar *value,
break;
default:
len = len / gimp_unit_get_factor (unit) * resolution;
*scale = len / reference;
*scale = resolution / gimp_unit_get_factor (unit);
*length = len;
}
@ -609,6 +641,10 @@ parse_svg_viewbox (const gchar *value,
*width = *height = 0.0;
}
}
else
{
g_printerr ("SVG import: cannot parse viewBox attribute\n");
}
return success;
}

View File

@ -26,6 +26,7 @@
gboolean gimp_vectors_import (GimpImage *image,
const gchar *filename,
gboolean merge,
gboolean scale,
GError **error);

View File

@ -561,6 +561,7 @@ gimp_path_to_selection (gint32 image_ID,
* @image_ID: The image.
* @filename: The name of the SVG file to import.
* @merge: Merge paths into a single vectors object.
* @scale: Scale the SVG to image dimensions.
*
* Import paths from an SVG file.
*
@ -573,7 +574,8 @@ gimp_path_to_selection (gint32 image_ID,
gboolean
gimp_path_import (gint32 image_ID,
const gchar *filename,
gboolean merge)
gboolean merge,
gboolean scale)
{
GimpParam *return_vals;
gint nreturn_vals;
@ -584,6 +586,7 @@ gimp_path_import (gint32 image_ID,
GIMP_PDB_IMAGE, image_ID,
GIMP_PDB_STRING, filename,
GIMP_PDB_INT32, merge,
GIMP_PDB_INT32, scale,
GIMP_PDB_END);
success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;

View File

@ -72,7 +72,8 @@ gboolean gimp_path_to_selection (gint32 image_ID,
gdouble feather_radius_y);
gboolean gimp_path_import (gint32 image_ID,
const gchar *filename,
gboolean merge);
gboolean merge,
gboolean scale);
G_END_DECLS

View File

@ -207,7 +207,8 @@ run (const gchar *name,
{
if (load_vals.import)
gimp_path_import (image_ID,
param[1].data.d_string, load_vals.merge);
param[1].data.d_string,
load_vals.merge, TRUE);
*nreturn_vals = 2;
values[1].type = GIMP_PDB_IMAGE;
@ -781,18 +782,6 @@ load_dialog (const gchar *filename)
NULL);
/* Scale ratio */
label = gtk_label_new (_("Ratio X:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (label);
label = gtk_label_new (_("Y:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (label);
hbox = gtk_hbox_new (FALSE, 0);
gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 2, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
@ -818,6 +807,13 @@ load_dialog (const gchar *filename)
G_CALLBACK (load_dialog_ratio_callback),
NULL);
label = gtk_label_new_with_mnemonic (_("Ratio _X:"));
gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton);
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (label);
spinbutton =
gimp_spin_button_new (&yadj,
ratio_y,
@ -833,6 +829,13 @@ load_dialog (const gchar *filename)
G_CALLBACK (load_dialog_ratio_callback),
NULL);
label = gtk_label_new_with_mnemonic (_("_Y:"));
gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton);
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (label);
/* the constrain ratio chainbutton */
constrain = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (constrain), TRUE);
@ -872,14 +875,13 @@ load_dialog (const gchar *filename)
/* Path Import */
toggle = gtk_check_button_new_with_mnemonic (_("Import _Paths"));
gtk_table_attach (GTK_TABLE (table), toggle, 1, 2, 5, 6,
gtk_table_attach (GTK_TABLE (table), toggle, 0, 2, 5, 6,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (toggle);
gimp_help_set_help_data (toggle,
_("Import path elements of the SVG so they can be "
"used with the GIMP path tool. This may not work "
"properly with import ratios other than 1.0."),
_("Import path elements of the SVG so they "
"can be used with the GIMP path tool"),
NULL);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), load_vals.import);
@ -892,7 +894,7 @@ load_dialog (const gchar *filename)
NULL);
toggle2 = gtk_check_button_new_with_mnemonic (_("Merge Imported Paths"));
gtk_table_attach (GTK_TABLE (table), toggle2, 1, 2, 6, 7,
gtk_table_attach (GTK_TABLE (table), toggle2, 0, 2, 6, 7,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_set_sensitive (toggle2, load_vals.import);
gtk_widget_show (toggle2);

View File

@ -636,12 +636,14 @@ HELP
{ name => 'filename', type => 'string', no_validate => 1,
desc => 'The name of the SVG file to import.' },
{ name => 'merge', type => 'boolean',
desc => 'Merge paths into a single vectors object' }
desc => 'Merge paths into a single vectors object' },
{ name => 'scale', type => 'boolean',
desc => 'Scale the SVG to image dimensions' }
);
%invoke = (
headers => [ qw("vectors/gimpvectors-import.h") ],
code => 'success = gimp_vectors_import (gimage, filename, merge, NULL);'
code => 'success = gimp_vectors_import (gimage, filename, merge, scale, NULL);'
);
}