home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1995 Spencer Kimball and Peter Mattis
- *
- * This is a plug-in for the GIMP.
- *
- * Plugin to convert a selection to a path.
- *
- * Copyright (C) 1999 Andy Thomas alt@gimp.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
- /* Change log:-
- * 0.1 First version.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <types.h>
-
-
- #include <libgimp/gimp.h>
- #include <libgimp/gimpui.h>
-
-
- #define SCALE_WIDTH 100
-
- static GSList * adjust_widgets = NULL;
-
-
- /* Reset to recommended defaults */
- void
- reset_adv_dialog (void)
- {
- GSList *list;
- GtkObject *widget;
- gdouble *value;
-
- for (list = adjust_widgets; list; list = g_slist_next (list))
- {
- widget = GTK_OBJECT (list->data);
- value = (gdouble *) gtk_object_get_data (widget ,"default_value");
-
- if (GTK_IS_ADJUSTMENT (widget))
- {
- gtk_adjustment_set_value (GTK_ADJUSTMENT (widget),
- *value);
- }
- else if (GTK_IS_TOGGLE_BUTTON (widget))
- {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
- (gboolean)(*value));
- }
- else
- g_warning ("Internal widget list error");
- }
- }
-
- gpointer
- def_val (gdouble default_value)
- {
- gdouble *value = g_new0 (gdouble, 1);
- *value = default_value;
- return (value);
- }
-
- GtkWidget *
- dialog_create_selection_area (SELVALS *sels)
- {
- GtkWidget *table;
- GtkWidget *check;
- GtkObject *adj;
- gint row;
-
- gimp_help_init ();
-
- table = gtk_table_new (20, 3, FALSE);
- gtk_table_set_row_spacings (GTK_TABLE (table), 2);
- gtk_table_set_col_spacings (GTK_TABLE (table), 2);
- row = 0;
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Align Threshold:", SCALE_WIDTH, 0,
- sels->align_threshold,
- 0.2, 2.0, 0.1, 0.1, 2,
- TRUE, 0, 0,
- "If two endpoints are closer than this,"
- "they are made to be equal.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->align_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.5));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Corner Always Threshold:", SCALE_WIDTH, 0,
- sels->corner_always_threshold,
- 30, 180, 1, 1, 2,
- TRUE, 0, 0,
- "If the angle defined by a point and its predecessors "
- "and successors is smaller than this, it's a corner, "
- "even if it's within `corner_surround' pixels of a "
- "point with a smaller angle.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->corner_always_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (60.0));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Corner Surround:", SCALE_WIDTH, 0,
- sels->corner_surround,
- 3, 8, 1, 1, 0,
- TRUE, 0, 0,
- "Number of points to consider when determining if a "
- "point is a corner or not.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->corner_surround);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (4.0));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Corner Threshold:", SCALE_WIDTH, 0,
- sels->corner_threshold,
- 0, 180, 1, 1, 2,
- TRUE, 0, 0,
- "If a point, its predecessors, and its successors "
- "define an angle smaller than this, it's a corner.",
- NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->corner_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (100.0));
-
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Error Threshold:", SCALE_WIDTH, 0,
- sels->error_threshold,
- 0.2, 10, 0.1, 0.1, 2,
- TRUE, 0, 0,
- "Amount of error at which a fitted spline is "
- "unacceptable. If any pixel is further away "
- "than this from the fitted curve, we try again.",
- NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->error_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.40));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Filter Alternative Surround:", SCALE_WIDTH, 0,
- sels->filter_alternative_surround,
- 1, 10, 1, 1, 0,
- TRUE, 0, 0,
- "A second number of adjacent points to consider "
- "when filtering.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->filter_alternative_surround);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (1.0));
-
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Filter Epsilon:", SCALE_WIDTH, 0,
- sels->filter_epsilon,
- 5, 40, 1, 1, 2,
- TRUE, 0, 0,
- "If the angles between the vectors produced by "
- "filter_surround and filter_alternative_surround "
- "points differ by more than this, use the one from "
- "filter_alternative_surround.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->filter_epsilon);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (10.0));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Filter Iteration Count:", SCALE_WIDTH, 0,
- sels->filter_iteration_count,
- 4, 70, 1, 1, 0,
- TRUE, 0, 0,
- "Number of times to smooth original data points. "
- "Increasing this number dramatically --- to 50 or "
- "so --- can produce vastly better results. But if "
- "any points that ``should'' be corners aren't found, "
- "the curve goes to hell around that point.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->filter_iteration_count);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (4.0));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Filter Percent:", SCALE_WIDTH, 0,
- sels->filter_percent,
- 0, 1, 0.05, 0.01, 2,
- TRUE, 0, 0,
- "To produce the new point, use the old point plus "
- "this times the neighbors.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->filter_percent);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.33));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Filter Secondary Surround:", SCALE_WIDTH, 0,
- sels->filter_secondary_surround,
- 3, 10, 1, 1, 0,
- TRUE, 0, 0,
- "Number of adjacent points to consider if "
- "`filter_surround' points defines a straight line.",
- NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->filter_secondary_surround);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (3.0));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Filter Surround:", SCALE_WIDTH, 0,
- sels->filter_surround,
- 2, 10, 1, 1, 0,
- TRUE, 0, 0,
- "Number of adjacent points to consider when filtering.",
- NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->filter_surround);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (2.0));
-
- check = gtk_check_button_new_with_label ("Keep Knees");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), sels->keep_knees);
- gtk_table_attach (GTK_TABLE (table), check, 1, 3, row, row + 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- gimp_help_set_help_data (GTK_WIDGET (check),
- "Says whether or not to remove ``knee'' "
- "points after finding the outline.", NULL);
- gtk_signal_connect (GTK_OBJECT (check), "toggled",
- GTK_SIGNAL_FUNC (gimp_toggle_button_update),
- &sels->keep_knees);
- gtk_widget_show (check);
- adjust_widgets = g_slist_append (adjust_widgets, check);
- gtk_object_set_data (GTK_OBJECT (check), "default_value", def_val ((gdouble)FALSE));
- row++;
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Line Reversion Threshold:", SCALE_WIDTH, 0,
- sels->line_reversion_threshold,
- 0.01, 0.2, 0.01, 0.01, 3,
- TRUE, 0, 0,
- "If a spline is closer to a straight line than this, "
- "it remains a straight line, even if it would otherwise "
- "be changed back to a curve. This is weighted by the "
- "square of the curve length, to make shorter curves "
- "more likely to be reverted.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->line_reversion_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.01));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Line Threshold:", SCALE_WIDTH, 0,
- sels->line_threshold,
- 0.2, 4, 0.1, 0.01, 2,
- TRUE, 0, 0,
- "How many pixels (on the average) a spline can "
- "diverge from the line determined by its endpoints "
- "before it is changed to a straight line.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->line_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.5));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Reparametrize Improvement:", SCALE_WIDTH, 0,
- sels->reparameterize_improvement,
- 0, 1, 0.05, 0.01, 2,
- TRUE, 0, 0,
- "If reparameterization doesn't improve the fit by this "
- "much percent, stop doing it. ""Amount of error at which "
- "it is pointless to reparameterize.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->reparameterize_improvement);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.01));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Reparametrize Threshold:", SCALE_WIDTH, 0,
- sels->reparameterize_threshold,
- 1, 50, 0.5, 0.5, 2,
- TRUE, 0, 0,
- "Amount of error at which it is pointless to reparameterize. "
- "This happens, for example, when we are trying to fit the "
- "outline of the outside of an `O' with a single spline. "
- "The initial fit is not good enough for the Newton-Raphson "
- "iteration to improve it. It may be that it would be better "
- "to detect the cases where we didn't find any corners.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->reparameterize_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (1.0));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Subdivide Search:", SCALE_WIDTH, 0,
- sels->subdivide_search,
- 0.05, 1, 0.05, 0.01, 2,
- TRUE, 0, 0,
- "Percentage of the curve away from the worst point "
- "to look for a better place to subdivide.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->subdivide_search);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.1));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Subdivide Surround:", SCALE_WIDTH, 0,
- sels->subdivide_surround,
- 2, 10, 1, 1, 0,
- TRUE, 0, 0,
- "Number of points to consider when deciding whether "
- "a given point is a better place to subdivide.",
- NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->subdivide_surround);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (4.0));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Subdivide Threshold:", SCALE_WIDTH, 0,
- sels->subdivide_threshold,
- 0.01, 1, 0.01, 0.01, 2,
- TRUE, 0, 0,
- "How many pixels a point can diverge from a straight "
- "line and still be considered a better place to "
- "subdivide.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->subdivide_threshold);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (0.03));
-
- adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
- "Tangent Surround:", SCALE_WIDTH, 0,
- sels->tangent_surround,
- 2, 10, 1, 1, 0,
- TRUE, 0, 0,
- "Number of points to look at on either side of a "
- "point when computing the approximation to the "
- "tangent at that point.", NULL);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
- &sels->tangent_surround);
- adjust_widgets = g_slist_append (adjust_widgets, adj);
- gtk_object_set_data (GTK_OBJECT (adj), "default_value", def_val (3.0));
-
- return GTK_WIDGET(table);
- }
-
-
-
-