mirror of https://github.com/GNOME/gimp.git
libgimp, plug-ins: GimpVectorLoadProcedureDialog will have thumbnail and…
… native dimensions/ratio display by default. Also adding gimp_vector_load_procedure_extract_dimensions() public function allowing plug-ins to query the native size or ratio of a vector file.
This commit is contained in:
parent
a4bb3a48a2
commit
221bdd61c6
|
@ -884,6 +884,7 @@ EXPORTS
|
|||
gimp_tile_height
|
||||
gimp_tile_width
|
||||
gimp_user_time
|
||||
gimp_vector_load_procedure_extract_dimensions
|
||||
gimp_vector_load_procedure_get_type
|
||||
gimp_vector_load_procedure_new
|
||||
gimp_vectors_bezier_stroke_conicto
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
*
|
||||
* When invoked via [method@Procedure.run], it unpacks these standard
|
||||
* arguments and calls @run_func which is a [callback@RunImageFunc]. The
|
||||
* [class@ProcedureConfig] of [callback@GimpRunVectorLoadFunc] contains
|
||||
* [class@ProcedureConfig] of [callback@Gimp.RunVectorLoadFunc] contains
|
||||
* additionally added arguments but also the arguments added by this class.
|
||||
*/
|
||||
|
||||
|
@ -527,3 +527,79 @@ gimp_vector_load_procedure_new (GimpPlugIn *plug_in,
|
|||
|
||||
return GIMP_PROCEDURE (procedure);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_vector_load_procedure_extract_dimensions:
|
||||
* @procedure: the associated #GimpVectorLoadProcedure.
|
||||
* @file: a [iface@Gio.File] which can be processed by @procedure.
|
||||
* @data: (out): the returned dimension data.
|
||||
* @error: (out): the #GError in case of error.
|
||||
*
|
||||
* Extracts native or suggested dimensions from @file, which must be a vector
|
||||
* file in the right format supported by @procedure. It is considered a
|
||||
* programming error to pass a file of invalid format.
|
||||
*
|
||||
* Returns: %TRUE if dimensions could be extracted.
|
||||
*/
|
||||
gboolean
|
||||
gimp_vector_load_procedure_extract_dimensions (GimpVectorLoadProcedure *procedure,
|
||||
GFile *file,
|
||||
GimpVectorLoadData *data,
|
||||
GError **error)
|
||||
{
|
||||
gboolean extract_success = FALSE;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_VECTOR_LOAD_PROCEDURE (procedure), FALSE);
|
||||
g_return_val_if_fail (G_IS_FILE (file), FALSE);
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (procedure->extract_func)
|
||||
{
|
||||
gchar *mimetype = NULL;
|
||||
GimpMetadata *metadata = NULL;
|
||||
gpointer data_for_run = NULL;
|
||||
GDestroyNotify data_for_run_destroy = NULL;
|
||||
|
||||
mimetype = (gchar *) gimp_file_procedure_get_mime_types (GIMP_FILE_PROCEDURE (procedure));
|
||||
|
||||
if (mimetype != NULL)
|
||||
{
|
||||
char *delim;
|
||||
|
||||
mimetype = g_strdup (mimetype);
|
||||
mimetype = g_strstrip (mimetype);
|
||||
delim = strstr (mimetype, ",");
|
||||
if (delim)
|
||||
*delim = '\0';
|
||||
/* Though docs only writes about the list being comma-separated, our
|
||||
* code apparently also split by spaces.
|
||||
*/
|
||||
delim = strstr (mimetype, " ");
|
||||
if (delim)
|
||||
*delim = '\0';
|
||||
delim = strstr (mimetype, "\t");
|
||||
if (delim)
|
||||
*delim = '\0';
|
||||
|
||||
metadata = gimp_metadata_load_from_file (file, NULL);
|
||||
g_free (mimetype);
|
||||
}
|
||||
|
||||
if (metadata == NULL)
|
||||
metadata = gimp_metadata_new ();
|
||||
|
||||
extract_success = procedure->extract_func (GIMP_PROCEDURE (procedure),
|
||||
GIMP_RUN_NONINTERACTIVE,
|
||||
file, metadata, NULL,
|
||||
data, &data_for_run, &data_for_run_destroy,
|
||||
procedure->extract_data, error);
|
||||
|
||||
if (data_for_run_destroy)
|
||||
data_for_run_destroy (data_for_run);
|
||||
|
||||
g_clear_object (&metadata);
|
||||
}
|
||||
|
||||
return extract_success;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ typedef GimpValueArray * (* GimpRunVectorLoadFunc) (GimpProcedure
|
|||
* @procedure: the [class@Gimp.Procedure].
|
||||
* @run_mode: the [enum@RunMode].
|
||||
* @metadata: the [class@Gimp.Metadata] which will be added to the new image.
|
||||
* @config: the @procedure's remaining arguments.
|
||||
* @config: (nullable): the @procedure's remaining arguments.
|
||||
* @file: the [iface@Gio.File] to load from.
|
||||
* @extracted_data: (out): dimensions and pixel density extracted from @file.
|
||||
* @data_for_run: (out) (nullable): will be passed as @data_from_extract in [callback@RunVectorLoadFunc].
|
||||
|
@ -138,7 +138,13 @@ typedef GimpValueArray * (* GimpRunVectorLoadFunc) (GimpProcedure
|
|||
* will still be called but default values might be bogus.
|
||||
* If the return value is %FALSE and %error is set, it means that the file is
|
||||
* invalid and cannot even be loaded. Thus [callback@RunVectorLoadFunc] won't be
|
||||
* run and %error
|
||||
* run and %error is passed as the main run error.
|
||||
*
|
||||
* Note: when @procedure is run, the original arguments will be passed as
|
||||
* @config. Nevertheless it may happen that this function is called with a %NULL
|
||||
* @config, in particular when [method@VectorLoadProcedure.extract_dimensions] is
|
||||
* called. In such a case, the callback is expected to return whatever can be
|
||||
* considered "best judgement" defaults.
|
||||
*
|
||||
* Returns: %TRUE if any information could be extracted from @file.
|
||||
*
|
||||
|
@ -162,15 +168,20 @@ G_DECLARE_FINAL_TYPE (GimpVectorLoadProcedure, gimp_vector_load_procedure, GIMP,
|
|||
typedef struct _GimpVectorLoadProcedure GimpVectorLoadProcedure;
|
||||
|
||||
|
||||
GimpProcedure * gimp_vector_load_procedure_new (GimpPlugIn *plug_in,
|
||||
const gchar *name,
|
||||
GimpPDBProcType proc_type,
|
||||
GimpExtractVectorFunc extract_func,
|
||||
gpointer extract_data,
|
||||
GDestroyNotify extract_data_destroy,
|
||||
GimpRunVectorLoadFunc run_func,
|
||||
gpointer run_data,
|
||||
GDestroyNotify run_data_destroy);
|
||||
GimpProcedure * gimp_vector_load_procedure_new (GimpPlugIn *plug_in,
|
||||
const gchar *name,
|
||||
GimpPDBProcType proc_type,
|
||||
GimpExtractVectorFunc extract_func,
|
||||
gpointer extract_data,
|
||||
GDestroyNotify extract_data_destroy,
|
||||
GimpRunVectorLoadFunc run_func,
|
||||
gpointer run_data,
|
||||
GDestroyNotify run_data_destroy);
|
||||
|
||||
gboolean gimp_vector_load_procedure_extract_dimensions (GimpVectorLoadProcedure *procedure,
|
||||
GFile *file,
|
||||
GimpVectorLoadData *data,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -35,18 +35,22 @@
|
|||
|
||||
struct _GimpVectorLoadProcedureDialogPrivate
|
||||
{
|
||||
/* TODO: add thumbnail support from the file. */
|
||||
GFile *file;
|
||||
GFile *file;
|
||||
GimpVectorLoadData *extracted_data;
|
||||
};
|
||||
|
||||
|
||||
static void gimp_vector_load_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config,
|
||||
GList *properties);
|
||||
static void gimp_vector_load_procedure_dialog_fill_start (GimpProcedureDialog *dialog,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config);
|
||||
static void gimp_vector_load_procedure_dialog_fill_start (GimpProcedureDialog *dialog,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config);
|
||||
static void gimp_vector_load_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config,
|
||||
GList *properties);
|
||||
|
||||
static void gimp_vector_load_procedure_dialog_preview_allocate (GtkWidget *gtk_image,
|
||||
GtkAllocation *allocation,
|
||||
GimpVectorLoadProcedureDialog *dialog);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpVectorLoadProcedureDialog, gimp_vector_load_procedure_dialog, GIMP_TYPE_PROCEDURE_DIALOG)
|
||||
|
@ -56,9 +60,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (GimpVectorLoadProcedureDialog, gimp_vector_load_proc
|
|||
static void
|
||||
gimp_vector_load_procedure_dialog_class_init (GimpVectorLoadProcedureDialogClass *klass)
|
||||
{
|
||||
GimpProcedureDialogClass *proc_dialog_class;
|
||||
|
||||
proc_dialog_class = GIMP_PROCEDURE_DIALOG_CLASS (klass);
|
||||
GimpProcedureDialogClass *proc_dialog_class = GIMP_PROCEDURE_DIALOG_CLASS (klass);
|
||||
|
||||
proc_dialog_class->fill_start = gimp_vector_load_procedure_dialog_fill_start;
|
||||
proc_dialog_class->fill_list = gimp_vector_load_procedure_dialog_fill_list;
|
||||
|
@ -77,19 +79,127 @@ gimp_vector_load_procedure_dialog_fill_start (GimpProcedureDialog *dialog,
|
|||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config)
|
||||
{
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *res_entry;
|
||||
GimpVectorLoadProcedureDialog *vector_dialog = GIMP_VECTOR_LOAD_PROCEDURE_DIALOG (dialog);
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *top_hbox;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *res_entry;
|
||||
GtkWidget *label;
|
||||
gchar *text = NULL;
|
||||
gchar *markup = NULL;
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), main_vbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (main_vbox);
|
||||
|
||||
top_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), top_hbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (top_hbox);
|
||||
|
||||
/* Resolution */
|
||||
res_entry = gimp_prop_resolution_entry_new (G_OBJECT (config),
|
||||
"width", "height", "pixel-density",
|
||||
"physical-unit");
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (content_area), res_entry, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (top_hbox), res_entry, FALSE, FALSE, 0);
|
||||
gtk_widget_show (res_entry);
|
||||
|
||||
/* Preview */
|
||||
|
||||
if (vector_dialog->priv->file)
|
||||
{
|
||||
GtkWidget *image;
|
||||
|
||||
image = gtk_image_new ();
|
||||
g_signal_connect (image, "size-allocate",
|
||||
G_CALLBACK (gimp_vector_load_procedure_dialog_preview_allocate),
|
||||
dialog);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (top_hbox), image, FALSE, FALSE, 0);
|
||||
gtk_widget_show (image);
|
||||
}
|
||||
|
||||
if (vector_dialog->priv->extracted_data)
|
||||
{
|
||||
if (vector_dialog->priv->extracted_data->exact_width && vector_dialog->priv->extracted_data->exact_height)
|
||||
{
|
||||
/* TRANSLATORS: the %s is a vector format name, e.g. "SVG" or "PDF",
|
||||
* followed by 2D dimensions with unit, e.g. "200 inch x 400 inch"
|
||||
*/
|
||||
text = g_strdup_printf (_("Source %s file size: %%.%df %s × %%.%df %s"),
|
||||
gimp_file_procedure_get_format_name (GIMP_FILE_PROCEDURE (procedure)),
|
||||
gimp_unit_get_digits (vector_dialog->priv->extracted_data->width_unit),
|
||||
gimp_unit_get_abbreviation (vector_dialog->priv->extracted_data->width_unit),
|
||||
gimp_unit_get_digits (vector_dialog->priv->extracted_data->height_unit),
|
||||
gimp_unit_get_abbreviation (vector_dialog->priv->extracted_data->height_unit));
|
||||
markup = g_strdup_printf (text, vector_dialog->priv->extracted_data->width, vector_dialog->priv->extracted_data->height);
|
||||
}
|
||||
else if (vector_dialog->priv->extracted_data->correct_ratio)
|
||||
{
|
||||
gdouble ratio_width = 0.0;
|
||||
gint ratio_width_digits = 0;
|
||||
gdouble ratio_height = 0.0;
|
||||
gint ratio_height_digits = 0;
|
||||
|
||||
if (vector_dialog->priv->extracted_data->width_unit == vector_dialog->priv->extracted_data->height_unit)
|
||||
{
|
||||
ratio_width = vector_dialog->priv->extracted_data->width;
|
||||
ratio_height = vector_dialog->priv->extracted_data->height;
|
||||
if (vector_dialog->priv->extracted_data->width_unit == GIMP_UNIT_PIXEL ||
|
||||
vector_dialog->priv->extracted_data->width_unit == GIMP_UNIT_PERCENT)
|
||||
ratio_width_digits = ratio_height_digits = 0;
|
||||
else
|
||||
ratio_width_digits = ratio_height_digits = gimp_unit_get_digits (vector_dialog->priv->extracted_data->width_unit);
|
||||
}
|
||||
else if (vector_dialog->priv->extracted_data->width_unit != GIMP_UNIT_PIXEL && vector_dialog->priv->extracted_data->height_unit != GIMP_UNIT_PIXEL &&
|
||||
vector_dialog->priv->extracted_data->width_unit != GIMP_UNIT_PERCENT && vector_dialog->priv->extracted_data->height_unit != GIMP_UNIT_PERCENT)
|
||||
{
|
||||
ratio_width = vector_dialog->priv->extracted_data->width / gimp_unit_get_factor (vector_dialog->priv->extracted_data->width_unit);
|
||||
ratio_height = vector_dialog->priv->extracted_data->height / gimp_unit_get_factor (vector_dialog->priv->extracted_data->height_unit);
|
||||
|
||||
ratio_width_digits = ratio_height_digits = gimp_unit_get_digits (GIMP_UNIT_INCH);
|
||||
}
|
||||
|
||||
if (ratio_width != 0.0 && ratio_height != 0.0)
|
||||
{
|
||||
/* TRANSLATOR: the %s is a vector format name, e.g. "SVG" or "PDF". */
|
||||
text = g_strdup_printf (_("Source %s file's aspect ratio: %%.%df × %%.%df"),
|
||||
gimp_file_procedure_get_format_name (GIMP_FILE_PROCEDURE (procedure)),
|
||||
ratio_width_digits, ratio_height_digits);
|
||||
markup = g_strdup_printf (text, ratio_width, ratio_height);
|
||||
}
|
||||
}
|
||||
else if (vector_dialog->priv->extracted_data->width != 0.0 && vector_dialog->priv->extracted_data->height != 0.0)
|
||||
{
|
||||
text = g_strdup_printf (_("Approximated source %s file size: %%.%df %s × %%.%df %s"),
|
||||
gimp_file_procedure_get_format_name (GIMP_FILE_PROCEDURE (procedure)),
|
||||
gimp_unit_get_digits (vector_dialog->priv->extracted_data->width_unit),
|
||||
gimp_unit_get_abbreviation (vector_dialog->priv->extracted_data->width_unit),
|
||||
gimp_unit_get_digits (vector_dialog->priv->extracted_data->height_unit),
|
||||
gimp_unit_get_abbreviation (vector_dialog->priv->extracted_data->height_unit));
|
||||
markup = g_strdup_printf (text, vector_dialog->priv->extracted_data->width, vector_dialog->priv->extracted_data->height);
|
||||
}
|
||||
}
|
||||
|
||||
if (markup == NULL)
|
||||
{
|
||||
/* TRANSLATOR: the %s is a vector format name, e.g. "SVG" or "PDF". */
|
||||
text = g_strdup_printf (_("The source %s file does not specify a size!"),
|
||||
gimp_file_procedure_get_format_name (GIMP_FILE_PROCEDURE (procedure)));
|
||||
markup = g_strdup_printf ("<i>%s</i>", text);
|
||||
}
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), label, TRUE, TRUE, 4);
|
||||
gtk_widget_show (label);
|
||||
|
||||
g_free (text);
|
||||
g_free (markup);
|
||||
|
||||
GIMP_PROCEDURE_DIALOG_CLASS (parent_class)->fill_start (dialog, procedure, config);
|
||||
}
|
||||
|
||||
|
@ -122,13 +232,77 @@ gimp_vector_load_procedure_dialog_fill_list (GimpProcedureDialog *dialog,
|
|||
g_list_free (properties2);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_load_procedure_dialog_preview_allocate (GtkWidget *gtk_image,
|
||||
GtkAllocation *allocation,
|
||||
GimpVectorLoadProcedureDialog *dialog)
|
||||
{
|
||||
if (dialog->priv->file)
|
||||
{
|
||||
GimpProcedure *procedure = NULL;
|
||||
GimpValueArray *retval;
|
||||
GimpPDBStatusType status;
|
||||
|
||||
g_object_get (dialog, "procedure", &procedure, NULL);
|
||||
|
||||
retval = gimp_procedure_run (procedure,
|
||||
"file", dialog->priv->file,
|
||||
"width", allocation->height,
|
||||
"height", allocation->height,
|
||||
"keep-ratio", TRUE,
|
||||
NULL);
|
||||
|
||||
status = g_value_get_enum (gimp_value_array_index (retval, 0));
|
||||
|
||||
if (status == GIMP_PDB_SUCCESS)
|
||||
{
|
||||
GimpImage *image;
|
||||
GdkPixbuf *preview;
|
||||
|
||||
image = g_value_get_object (gimp_value_array_index (retval, 1));
|
||||
preview = gimp_image_get_thumbnail (image,
|
||||
gimp_image_get_width (image),
|
||||
gimp_image_get_height (image),
|
||||
GIMP_PIXBUF_SMALL_CHECKS);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (gtk_image), preview);
|
||||
gimp_image_delete (image);
|
||||
}
|
||||
|
||||
gimp_value_array_unref (retval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
|
||||
/**
|
||||
* gimp_vector_load_procedure_dialog_new:
|
||||
* @procedure: the associated #GimpVectorLoadProcedure.
|
||||
* @config: a #GimpProcedureConfig from which properties will be
|
||||
* turned into widgets.
|
||||
* @extracted_data: (nullable): the extracted dimensions of the file to load.
|
||||
* @file: (nullable): a [iface@Gio.File] to load the preview from.
|
||||
*
|
||||
* Creates a new dialog for @procedure using widgets generated from
|
||||
* properties of @config.
|
||||
*
|
||||
* @file must be the same vector file which was passed to the
|
||||
* [callback@Gimp.RunVectorLoadFunc] implementation for your plug-in. If you pass any
|
||||
* other file, then the preview may be wrong or not showing at all. And it is
|
||||
* considered a programming error.
|
||||
*
|
||||
* As for all #GtkWindow, the returned #GimpProcedureDialog object is
|
||||
* owned by GTK and its initial reference is stored in an internal list
|
||||
* of top-level windows. To delete the dialog, call
|
||||
* gtk_widget_destroy().
|
||||
*
|
||||
* Returns: (transfer none): the newly created #GimpVectorLoadProcedureDialog.
|
||||
*/
|
||||
GtkWidget *
|
||||
gimp_vector_load_procedure_dialog_new (GimpVectorLoadProcedure *procedure,
|
||||
GimpProcedureConfig *config,
|
||||
GimpVectorLoadData *extracted_data,
|
||||
GFile *file)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
@ -141,7 +315,7 @@ gimp_vector_load_procedure_dialog_new (GimpVectorLoadProcedure *procedure,
|
|||
g_return_val_if_fail (GIMP_IS_PROCEDURE_CONFIG (config), NULL);
|
||||
g_return_val_if_fail (gimp_procedure_config_get_procedure (config) ==
|
||||
GIMP_PROCEDURE (procedure), NULL);
|
||||
/*g_return_val_if_fail (G_IS_FILE (file), NULL);*/
|
||||
g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
|
||||
|
||||
format_name = gimp_file_procedure_get_format_name (GIMP_FILE_PROCEDURE (procedure));
|
||||
if (! format_name)
|
||||
|
@ -170,6 +344,7 @@ gimp_vector_load_procedure_dialog_new (GimpVectorLoadProcedure *procedure,
|
|||
"use-header-bar", use_header_bar,
|
||||
NULL);
|
||||
GIMP_VECTOR_LOAD_PROCEDURE_DIALOG (dialog)->priv->file = file;
|
||||
GIMP_VECTOR_LOAD_PROCEDURE_DIALOG (dialog)->priv->extracted_data = extracted_data;
|
||||
g_free (title);
|
||||
|
||||
return dialog;
|
||||
|
|
|
@ -68,6 +68,7 @@ GType gimp_vector_load_procedure_dialog_get_type (void) G_GNUC_CO
|
|||
|
||||
GtkWidget * gimp_vector_load_procedure_dialog_new (GimpVectorLoadProcedure *procedure,
|
||||
GimpProcedureConfig *config,
|
||||
GimpVectorLoadData *extracted_data,
|
||||
GFile *file);
|
||||
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ static GimpImage * load_image (PopplerDocument *doc,
|
|||
|
||||
static GimpPDBStatusType load_dialog (PopplerDocument *doc,
|
||||
PdfSelectedPages *pages,
|
||||
GimpVectorLoadData extracted_data,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config);
|
||||
|
||||
|
@ -371,7 +372,7 @@ pdf_load (GimpProcedure *procedure,
|
|||
}
|
||||
else if (run_mode == GIMP_RUN_INTERACTIVE)
|
||||
{
|
||||
status = load_dialog (doc, &pages, procedure, config);
|
||||
status = load_dialog (doc, &pages, extracted_data, procedure, config);
|
||||
}
|
||||
else if (run_mode == GIMP_RUN_NONINTERACTIVE)
|
||||
{
|
||||
|
@ -1036,6 +1037,7 @@ white_background_toggled (GtkToggleButton *widget,
|
|||
static GimpPDBStatusType
|
||||
load_dialog (PopplerDocument *doc,
|
||||
PdfSelectedPages *pages,
|
||||
GimpVectorLoadData extracted_data,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config)
|
||||
{
|
||||
|
@ -1060,7 +1062,7 @@ load_dialog (PopplerDocument *doc,
|
|||
|
||||
dialog = gimp_vector_load_procedure_dialog_new (GIMP_VECTOR_LOAD_PROCEDURE (procedure),
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
NULL);
|
||||
&extracted_data, NULL);
|
||||
|
||||
g_object_get (config,
|
||||
"target", &target,
|
||||
|
|
|
@ -281,10 +281,11 @@ static void dither_grey (const guchar *grey,
|
|||
|
||||
/* Dialog-handling */
|
||||
|
||||
static gint32 count_ps_pages (GFile *file);
|
||||
static gboolean load_dialog (GFile *file,
|
||||
GimpProcedure *procedure,
|
||||
GObject *config);
|
||||
static gint32 count_ps_pages (GFile *file);
|
||||
static gboolean load_dialog (GFile *file,
|
||||
GimpVectorLoadData extracted_data,
|
||||
GimpProcedure *procedure,
|
||||
GObject *config);
|
||||
|
||||
|
||||
typedef struct
|
||||
|
@ -663,7 +664,7 @@ ps_load (GimpProcedure *procedure,
|
|||
switch (run_mode)
|
||||
{
|
||||
case GIMP_RUN_INTERACTIVE:
|
||||
if (! load_dialog (file, procedure, G_OBJECT (config)))
|
||||
if (! load_dialog (file, extracted_data, procedure, G_OBJECT (config)))
|
||||
return gimp_procedure_new_return_values (procedure,
|
||||
GIMP_PDB_CANCEL,
|
||||
NULL);
|
||||
|
@ -3767,9 +3768,10 @@ count_ps_pages (GFile *file)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
load_dialog (GFile *file,
|
||||
GimpProcedure *procedure,
|
||||
GObject *config)
|
||||
load_dialog (GFile *file,
|
||||
GimpVectorLoadData extracted_data,
|
||||
GimpProcedure *procedure,
|
||||
GObject *config)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *hbox;
|
||||
|
@ -3786,7 +3788,7 @@ load_dialog (GFile *file,
|
|||
|
||||
dialog = gimp_vector_load_procedure_dialog_new (GIMP_VECTOR_LOAD_PROCEDURE (procedure),
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
NULL);
|
||||
&extracted_data, NULL);
|
||||
|
||||
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
|
||||
GTK_RESPONSE_OK,
|
||||
|
|
|
@ -778,85 +778,15 @@ load_dialog (GFile *file,
|
|||
GimpVectorLoadData extracted_data,
|
||||
GError **load_error)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *main_hbox;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *image;
|
||||
GdkPixbuf *preview;
|
||||
GtkWidget *label;
|
||||
gboolean run;
|
||||
GError *error = NULL;
|
||||
|
||||
preview = load_rsvg_pixbuf (handle,
|
||||
SVG_PREVIEW_SIZE, SVG_PREVIEW_SIZE, SVG_DEFAULT_RESOLUTION,
|
||||
&error);
|
||||
|
||||
if (! preview)
|
||||
{
|
||||
/* 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 GIMP_PDB_EXECUTION_ERROR;
|
||||
}
|
||||
GtkWidget *dialog;
|
||||
gboolean run;
|
||||
|
||||
gimp_ui_init (PLUG_IN_BINARY);
|
||||
|
||||
/* Scalable Vector Graphics is SVG, should perhaps not be translated */
|
||||
dialog = gimp_vector_load_procedure_dialog_new (GIMP_VECTOR_LOAD_PROCEDURE (procedure),
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
NULL);
|
||||
|
||||
main_hbox = gimp_procedure_dialog_fill_box (GIMP_PROCEDURE_DIALOG (dialog),
|
||||
"main-hbox", "paths", NULL);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (main_hbox), GTK_ORIENTATION_HORIZONTAL);
|
||||
|
||||
/* The SVG preview */
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||
gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
image = gtk_image_new_from_pixbuf (preview);
|
||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||
gtk_widget_show (image);
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 4);
|
||||
gtk_widget_show (label);
|
||||
|
||||
if (extracted_data.width >= 0.0 &&
|
||||
extracted_data.height >= 0.0 &&
|
||||
extracted_data.width_unit != GIMP_UNIT_PERCENT &&
|
||||
extracted_data.height_unit != GIMP_UNIT_PERCENT)
|
||||
{
|
||||
/* TRANSLATORS: these are 2D dimensions with unit, e.g. "200 inch x 400 inch" */
|
||||
gchar *text = g_strdup_printf (_("%.4f %s × %.4f %s"),
|
||||
extracted_data.width,
|
||||
gimp_unit_get_abbreviation (extracted_data.width_unit),
|
||||
extracted_data.height,
|
||||
gimp_unit_get_abbreviation (extracted_data.height_unit));
|
||||
gtk_label_set_text (GTK_LABEL (label), text);
|
||||
g_free (text);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (label),
|
||||
_("SVG file does not\nspecify a size!"));
|
||||
}
|
||||
|
||||
/* Complete the dialog. */
|
||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), "main-hbox", NULL);
|
||||
&extracted_data, file);
|
||||
gimp_procedure_dialog_fill (GIMP_PROCEDURE_DIALOG (dialog), NULL);
|
||||
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
|
|
|
@ -117,11 +117,9 @@ static gboolean load_wmf_size (GFile *file,
|
|||
float *height,
|
||||
gboolean *guessed);
|
||||
static gboolean load_dialog (GFile *file,
|
||||
GimpVectorLoadData extracted_data,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config);
|
||||
static WmfPixbuf * wmf_get_pixbuf (GFile *file,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static guchar * wmf_load_file (GFile *file,
|
||||
gint requested_width,
|
||||
gint requested_height,
|
||||
|
@ -273,7 +271,7 @@ wmf_load (GimpProcedure *procedure,
|
|||
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
if (run_mode == GIMP_RUN_INTERACTIVE && ! load_dialog (file, procedure, config))
|
||||
if (run_mode == GIMP_RUN_INTERACTIVE && ! load_dialog (file, extracted_data, procedure, config))
|
||||
return gimp_procedure_new_return_values (procedure,
|
||||
GIMP_PDB_CANCEL,
|
||||
NULL);
|
||||
|
@ -356,9 +354,6 @@ wmf_load_thumb (GimpProcedure *procedure,
|
|||
}
|
||||
|
||||
|
||||
static GtkWidget *size_label = NULL;
|
||||
|
||||
|
||||
/* This function retrieves the pixel size from a WMF file. */
|
||||
static gboolean
|
||||
load_wmf_size (GFile *file,
|
||||
|
@ -425,20 +420,6 @@ load_wmf_size (GFile *file,
|
|||
|
||||
if (guessed)
|
||||
*guessed = TRUE;
|
||||
|
||||
if (size_label)
|
||||
gtk_label_set_text (GTK_LABEL (size_label),
|
||||
_("WMF file does not\nspecify a size!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size_label)
|
||||
{
|
||||
gchar *text = g_strdup_printf (_("%.4f × %.4f"), *width, *height);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (size_label), text);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -447,36 +428,20 @@ load_wmf_size (GFile *file,
|
|||
|
||||
/* User interface */
|
||||
|
||||
static void
|
||||
wmf_preview_callback (GtkWidget *widget,
|
||||
GtkAllocation *allocation,
|
||||
WmfPixbuf *pixbuf)
|
||||
{
|
||||
gimp_preview_area_draw (GIMP_PREVIEW_AREA (widget),
|
||||
0, 0, pixbuf->width, pixbuf->height,
|
||||
GIMP_RGBA_IMAGE,
|
||||
pixbuf->pixels, pixbuf->width * 4);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_dialog (GFile *file,
|
||||
GimpVectorLoadData extracted_data,
|
||||
GimpProcedure *procedure,
|
||||
GimpProcedureConfig *config)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *image;
|
||||
WmfPixbuf *pixbuf;
|
||||
gboolean run = FALSE;
|
||||
WmfLoadVals vals;
|
||||
GtkWidget *dialog;
|
||||
gboolean run = FALSE;
|
||||
|
||||
gimp_ui_init (PLUG_IN_BINARY);
|
||||
|
||||
dialog = gimp_vector_load_procedure_dialog_new (GIMP_VECTOR_LOAD_PROCEDURE (procedure),
|
||||
GIMP_PROCEDURE_CONFIG (config),
|
||||
NULL);
|
||||
&extracted_data, file);
|
||||
|
||||
/* TODO: in the old version, there used to be X and Y ratio fields which could
|
||||
* be constrained/linked (or not) and would sync back and forth with the
|
||||
|
@ -484,42 +449,8 @@ load_dialog (GFile *file,
|
|||
* such UI when editing dimensions with options in GimpResolutionEntry?
|
||||
*/
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
/* The WMF preview */
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0);
|
||||
gtk_box_reorder_child (GTK_BOX (content_area), vbox, 0);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
vals.width = - WMF_PREVIEW_SIZE;
|
||||
vals.height = - WMF_PREVIEW_SIZE;
|
||||
pixbuf = wmf_get_pixbuf (file, &vals.width, &vals.height);
|
||||
image = gimp_preview_area_new ();
|
||||
gtk_widget_set_size_request (image, vals.width, vals.height);
|
||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||
gtk_widget_show (image);
|
||||
|
||||
g_signal_connect (image, "size-allocate",
|
||||
G_CALLBACK (wmf_preview_callback),
|
||||
pixbuf);
|
||||
|
||||
size_label = gtk_label_new (NULL);
|
||||
gtk_label_set_justify (GTK_LABEL (size_label), GTK_JUSTIFY_CENTER);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), size_label, TRUE, TRUE, 4);
|
||||
gtk_widget_show (size_label);
|
||||
|
||||
/* Run the dialog. */
|
||||
run = gimp_procedure_dialog_run (GIMP_PROCEDURE_DIALOG (dialog));
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
g_free (pixbuf->pixels);
|
||||
g_free (pixbuf);
|
||||
|
||||
return run;
|
||||
}
|
||||
|
@ -564,134 +495,6 @@ pixbuf_gd_convert (const gint *gd_pixels,
|
|||
return pixels;
|
||||
}
|
||||
|
||||
static WmfPixbuf *
|
||||
wmf_get_pixbuf (GFile *file,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
WmfPixbuf *pixbuf = NULL;
|
||||
GMappedFile *mapped;
|
||||
guchar *pixels = NULL;
|
||||
|
||||
/* the bits we need to decode the WMF via libwmf2's GD layer */
|
||||
wmf_error_t err;
|
||||
gulong flags;
|
||||
wmf_gd_t *ddata = NULL;
|
||||
wmfAPI *API = NULL;
|
||||
wmfAPI_Options api_options;
|
||||
guint file_width;
|
||||
guint file_height;
|
||||
wmfD_Rect bbox;
|
||||
gint *gd_pixels = NULL;
|
||||
char* wmffontdirs[2] = { NULL, NULL };
|
||||
|
||||
mapped = g_mapped_file_new (g_file_peek_path (file), FALSE, NULL);
|
||||
|
||||
if (! mapped)
|
||||
return NULL;
|
||||
|
||||
flags = WMF_OPT_IGNORE_NONFATAL | WMF_OPT_FUNCTION;
|
||||
api_options.function = wmf_gd_function;
|
||||
|
||||
#ifdef ENABLE_RELOCATABLE_RESOURCES
|
||||
wmffontdirs[0] = g_build_filename (gimp_installation_directory (),
|
||||
"share/libwmf/fonts", NULL);
|
||||
flags |= WMF_OPT_FONTDIRS;
|
||||
api_options.fontdirs = wmffontdirs;
|
||||
#endif
|
||||
|
||||
err = wmf_api_create (&API, flags, &api_options);
|
||||
if (wmffontdirs[0])
|
||||
g_free (wmffontdirs[0]);
|
||||
if (err != wmf_E_None)
|
||||
goto _wmf_error;
|
||||
|
||||
ddata = WMF_GD_GetData (API);
|
||||
ddata->type = wmf_gd_image;
|
||||
|
||||
err = wmf_mem_open (API,
|
||||
(guchar *) g_mapped_file_get_contents (mapped),
|
||||
g_mapped_file_get_length (mapped));
|
||||
if (err != wmf_E_None)
|
||||
goto _wmf_error;
|
||||
|
||||
err = wmf_scan (API, 0, &bbox);
|
||||
if (err != wmf_E_None)
|
||||
goto _wmf_error;
|
||||
|
||||
err = wmf_display_size (API, &file_width, &file_height,
|
||||
WMF_DEFAULT_RESOLUTION, WMF_DEFAULT_RESOLUTION);
|
||||
if (err != wmf_E_None || file_width <= 0 || file_height <= 0)
|
||||
goto _wmf_error;
|
||||
|
||||
if (!*width || !*height)
|
||||
goto _wmf_error;
|
||||
|
||||
/* either both arguments negative or none */
|
||||
if ((*width * *height) < 0)
|
||||
goto _wmf_error;
|
||||
|
||||
ddata->bbox = bbox;
|
||||
|
||||
if (*width > 0)
|
||||
{
|
||||
ddata->width = *width;
|
||||
ddata->height = *height;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdouble w = file_width;
|
||||
gdouble h = file_height;
|
||||
gdouble aspect = ((gdouble) *width) / (gdouble) *height;
|
||||
|
||||
if (aspect > (w / h))
|
||||
{
|
||||
ddata->height = abs (*height);
|
||||
ddata->width = (gdouble) abs (*width) * (w / h) + 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
ddata->width = abs (*width);
|
||||
ddata->height = (gdouble) abs (*height) / (w / h) + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
err = wmf_play (API, 0, &bbox);
|
||||
if (err != wmf_E_None)
|
||||
goto _wmf_error;
|
||||
|
||||
if (ddata->gd_image != NULL)
|
||||
gd_pixels = wmf_gd_image_pixels (ddata->gd_image);
|
||||
if (gd_pixels == NULL)
|
||||
goto _wmf_error;
|
||||
|
||||
pixels = pixbuf_gd_convert (gd_pixels, ddata->width, ddata->height);
|
||||
if (pixels == NULL)
|
||||
goto _wmf_error;
|
||||
|
||||
*width = ddata->width;
|
||||
*height = ddata->height;
|
||||
|
||||
_wmf_error:
|
||||
if (API)
|
||||
{
|
||||
wmf_mem_close (API);
|
||||
wmf_api_destroy (API);
|
||||
}
|
||||
|
||||
g_mapped_file_unref (mapped);
|
||||
|
||||
if (pixels)
|
||||
{
|
||||
pixbuf = g_new0 (WmfPixbuf, 1);
|
||||
pixbuf->pixels = pixels;
|
||||
pixbuf->width = *width;
|
||||
pixbuf->height = *height;
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
static guchar *
|
||||
wmf_load_file (GFile *file,
|
||||
gint requested_width,
|
||||
|
|
Loading…
Reference in New Issue