mirror of https://github.com/GNOME/gimp.git
Crop now does AutoShrink -- the algorithm starts with the interactively
1999-06-30 Sven Neumann <sven@gimp.org> * app/crop.c (crop_automatic_callback): Crop now does AutoShrink -- the algorithm starts with the interactively selected crop area and tries to shrink that instead of always starting from the corners. * plug-ins/helpbrowser/helpbrowser.c: cosmetic changes --Sven (using Mitschels account)
This commit is contained in:
parent
88d2b4ab61
commit
0320cb507e
|
@ -1,3 +1,12 @@
|
|||
1999-06-30 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/crop.c (crop_automatic_callback): Crop now does
|
||||
AutoShrink -- the algorithm starts with the interactively
|
||||
selected crop area and tries to shrink that instead of
|
||||
always starting from the corners.
|
||||
|
||||
* plug-ins/helpbrowser/helpbrowser.c: cosmetic changes
|
||||
|
||||
1999-06-28 Tor Lillqvist <tml@iki.fi>
|
||||
|
||||
* */makefile.msc: Use the DEBUG nmake variable to determine
|
||||
|
|
110
app/crop.c
110
app/crop.c
|
@ -137,7 +137,8 @@ typedef AutoCropType (*ColorsEqualFunc) (guchar *, guchar *, int);
|
|||
|
||||
static void crop_selection_callback (GtkWidget *, gpointer);
|
||||
static void crop_automatic_callback (GtkWidget *, gpointer);
|
||||
static AutoCropType crop_guess_bgcolor (GtkObject *, GetColorFunc, int, int, int, int, guchar *);
|
||||
static AutoCropType crop_guess_bgcolor (GtkObject *, GetColorFunc,
|
||||
int, int, guchar *, int, int, int, int);
|
||||
static int crop_colors_equal (guchar *, guchar *, int);
|
||||
static int crop_colors_alpha (guchar *, guchar *, int);
|
||||
|
||||
|
@ -1085,7 +1086,7 @@ crop_info_create (Tool *tool)
|
|||
(GtkSignalFunc) crop_selection_callback, NULL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Automatic"));
|
||||
button = gtk_button_new_with_label (_("Auto Shrink"));
|
||||
gtk_container_add(GTK_CONTAINER (bbox), button);
|
||||
gtk_signal_connect(GTK_OBJECT (button) , "clicked",
|
||||
(GtkSignalFunc) crop_automatic_callback, NULL);
|
||||
|
@ -1221,8 +1222,8 @@ crop_automatic_callback (GtkWidget *w,
|
|||
guchar bgcolor[4] = {0, 0, 0, 0};
|
||||
gint has_alpha = FALSE;
|
||||
PixelRegion PR;
|
||||
guchar *buffer;
|
||||
gint width, height, bytes;
|
||||
guchar *buffer = NULL;
|
||||
gint offset_x, offset_y, width, height, bytes;
|
||||
gint x, y, abort;
|
||||
gint x1, y1, x2, y2;
|
||||
|
||||
|
@ -1233,35 +1234,42 @@ crop_automatic_callback (GtkWidget *w,
|
|||
draw_core_pause (crop->core, tool);
|
||||
gimp_add_busy_cursors ();
|
||||
|
||||
/* You should always keep in mind that crop->tx2 and crop->ty2 are the NOT the
|
||||
coordinates of the bottomright corner of the area to be cropped. They point
|
||||
at the pixel located one to the right and one to the bottom.
|
||||
*/
|
||||
|
||||
if (crop_options->layer_only)
|
||||
{
|
||||
if (!(active_drawable = gimage_active_drawable (gdisp->gimage)))
|
||||
return;
|
||||
width = drawable_width (GIMP_DRAWABLE (active_drawable));
|
||||
width = drawable_width (GIMP_DRAWABLE (active_drawable));
|
||||
height = drawable_height (GIMP_DRAWABLE (active_drawable));
|
||||
bytes = drawable_bytes (GIMP_DRAWABLE (active_drawable));
|
||||
if (drawable_has_alpha (GIMP_DRAWABLE (active_drawable)))
|
||||
has_alpha = TRUE;
|
||||
get_color_obj = GTK_OBJECT (active_drawable);
|
||||
get_color_func = (GetColorFunc) gimp_drawable_get_color_at;
|
||||
drawable_offsets (GIMP_DRAWABLE (active_drawable), &crop->tx1, &crop->ty1);
|
||||
crop->tx2 = width + crop->tx1;
|
||||
crop->ty2 = height + crop->ty1;
|
||||
drawable_offsets (GIMP_DRAWABLE (active_drawable), &offset_x, &offset_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = gdisp->gimage->width;
|
||||
height = gdisp->gimage->height;
|
||||
has_alpha = TRUE;
|
||||
bytes = gimp_image_composite_bytes (gdisp->gimage);
|
||||
get_color_obj = GTK_OBJECT (gdisp->gimage);
|
||||
get_color_func = (GetColorFunc) gimp_image_get_color_at;
|
||||
bytes = gimp_image_composite_bytes (gdisp->gimage);
|
||||
has_alpha = TRUE;
|
||||
crop->tx1 = crop->ty1 = 0;
|
||||
crop->tx2 = width;
|
||||
crop->ty2 = height;
|
||||
}
|
||||
offset_x = offset_y = 0;
|
||||
}
|
||||
|
||||
switch (crop_guess_bgcolor (get_color_obj, get_color_func, width, height, bytes, has_alpha, bgcolor))
|
||||
x1 = crop->tx1 - offset_x > 0 ? crop->tx1 - offset_x : 0;
|
||||
x2 = crop->tx2 - offset_x < width ? crop->tx2 - offset_x : width;
|
||||
y1 = crop->ty1 - offset_y > 0 ? crop->ty1 - offset_y : 0;
|
||||
y2 = crop->ty2 - offset_y < height ? crop->ty2 - offset_y : height;
|
||||
|
||||
switch (crop_guess_bgcolor (get_color_obj, get_color_func, bytes, has_alpha,
|
||||
bgcolor, x1, x2-1, y1, y2-1))
|
||||
{
|
||||
case AUTO_CROP_ALPHA:
|
||||
colors_equal_func = (ColorsEqualFunc) crop_colors_alpha;
|
||||
|
@ -1273,68 +1281,76 @@ crop_automatic_callback (GtkWidget *w,
|
|||
goto FINISH;
|
||||
}
|
||||
|
||||
width = x2 - x1;
|
||||
height = y2 - y1;
|
||||
|
||||
if (crop_options->layer_only)
|
||||
pixel_region_init (&PR, drawable_data (active_drawable), 0, 0, width, height, FALSE);
|
||||
pixel_region_init (&PR, drawable_data (active_drawable),
|
||||
x1, y1, width, height, FALSE);
|
||||
else
|
||||
pixel_region_init (&PR, gimp_image_composite (gdisp->gimage), 0, 0, width, height, FALSE);
|
||||
pixel_region_init (&PR, gimp_image_composite (gdisp->gimage),
|
||||
x1, y1, width, height, FALSE);
|
||||
|
||||
buffer = g_malloc((width > height ? width : height) * bytes);
|
||||
/* The following could be optimized further by processing the smaller side first
|
||||
instead of defaulting to width --Sven
|
||||
*/
|
||||
|
||||
x1 = x2 = y1 = y2 = 0;
|
||||
buffer = g_malloc ((width > height ? width : height) * bytes);
|
||||
|
||||
/* Check how many of the top lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
for (y = y1; y < y2 && !abort; y++)
|
||||
{
|
||||
pixel_region_get_row (&PR, 0, y, width, buffer, 1);
|
||||
pixel_region_get_row (&PR, x1, y, width, buffer, 1);
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + x * bytes, bytes);
|
||||
}
|
||||
if (y == height && !abort) {
|
||||
g_free (buffer);
|
||||
if (y == y2 && !abort)
|
||||
goto FINISH;
|
||||
}
|
||||
y1 = y - 1;
|
||||
|
||||
/* Check how many of the bottom lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (y = height - 1; y >= y1 && !abort; y--)
|
||||
for (y = y2; y > y1 && !abort; y--)
|
||||
{
|
||||
pixel_region_get_row (&PR, 0, y, width, buffer, 1);
|
||||
pixel_region_get_row (&PR, x1, y-1 , width, buffer, 1);
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + x * bytes, bytes);
|
||||
}
|
||||
y2 = y + 1;
|
||||
|
||||
/* compute a new height for the next operations */
|
||||
height = y2 - y1;
|
||||
|
||||
/* Check how many of the left lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
for (x = x1; x < x2 && !abort; x++)
|
||||
{
|
||||
pixel_region_get_col (&PR, x, y1, y2 - y1 + 1, buffer, 1);
|
||||
for (y = 0; y <= (y2 - y1) && !abort; y++)
|
||||
pixel_region_get_col (&PR, x, y1, height, buffer, 1);
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + y * bytes, bytes);
|
||||
}
|
||||
x1 = x - 1;
|
||||
|
||||
/* Check how many of the right lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (x = width - 1; x >= x1 && !abort; x--)
|
||||
for (x = x2; x > x1 && !abort; x--)
|
||||
{
|
||||
pixel_region_get_col (&PR, x, y1, y2 - y1 + 1, buffer, 1);
|
||||
for (y = 0; y <= (y2 - y1) && !abort; y++)
|
||||
pixel_region_get_col (&PR, x-1, y1, height, buffer, 1);
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + y * bytes, bytes);
|
||||
}
|
||||
x2 = x + 1;
|
||||
|
||||
g_free (buffer);
|
||||
crop->tx1 = offset_x + x1;
|
||||
crop->tx2 = offset_x + x2;
|
||||
crop->ty1 = offset_y + y1;
|
||||
crop->ty2 = offset_y + y2;
|
||||
|
||||
crop->tx2 = crop->tx1 + x2 + 1;
|
||||
crop->ty2 = crop->ty1 + y2 + 1;
|
||||
crop->tx1 += x1;
|
||||
crop->ty1 += y1;
|
||||
crop_recalc (tool, crop);
|
||||
|
||||
FINISH:
|
||||
crop_recalc (tool, crop);
|
||||
g_free (buffer);
|
||||
gimp_remove_busy_cursors (NULL);
|
||||
draw_core_resume (crop->core, tool);
|
||||
|
||||
|
@ -1344,11 +1360,13 @@ crop_automatic_callback (GtkWidget *w,
|
|||
static AutoCropType
|
||||
crop_guess_bgcolor (GtkObject *get_color_obj,
|
||||
GetColorFunc get_color_func,
|
||||
int width,
|
||||
int height,
|
||||
int bytes,
|
||||
int has_alpha,
|
||||
guchar *color)
|
||||
guchar *color,
|
||||
int x1,
|
||||
int x2,
|
||||
int y1,
|
||||
int y2)
|
||||
{
|
||||
guchar *tl = NULL;
|
||||
guchar *tr = NULL;
|
||||
|
@ -1356,20 +1374,20 @@ crop_guess_bgcolor (GtkObject *get_color_obj,
|
|||
guchar *br = NULL;
|
||||
gint i, alpha;
|
||||
|
||||
for (i=0; i< bytes; i++)
|
||||
for (i = 0; i < bytes; i++)
|
||||
color[i] = 0;
|
||||
|
||||
/* First check if there's transparency to crop. If not, guess the
|
||||
* background-color to see if at least 2 corners are equal.
|
||||
*/
|
||||
|
||||
if (!(tl = (*get_color_func) (get_color_obj, 0, 0)))
|
||||
if (!(tl = (*get_color_func) (get_color_obj, x1, y1)))
|
||||
goto ERROR;
|
||||
if (!(tr = (*get_color_func) (get_color_obj, width - 1, 0)))
|
||||
if (!(tr = (*get_color_func) (get_color_obj, x1, y2)))
|
||||
goto ERROR;
|
||||
if (!(bl = (*get_color_func) (get_color_obj, 0, height - 1)))
|
||||
if (!(bl = (*get_color_func) (get_color_obj, x2, y1)))
|
||||
goto ERROR;
|
||||
if (!(br = (*get_color_func) (get_color_obj, width - 1, height - 1)))
|
||||
if (!(br = (*get_color_func) (get_color_obj, x2, y2)))
|
||||
goto ERROR;
|
||||
|
||||
if (has_alpha)
|
||||
|
|
|
@ -963,7 +963,7 @@ gimp_dialog_delete_callback (GtkWidget *widget,
|
|||
}
|
||||
|
||||
/*
|
||||
#include "/home/mitschel/wilber3.xpm"
|
||||
#include "/home/mitschel/gimpfiles/wilber.xpm"
|
||||
|
||||
static void
|
||||
gimp_dialog_realize_callback (GtkWidget *widget,
|
||||
|
@ -980,7 +980,7 @@ gimp_dialog_realize_callback (GtkWidget *widget,
|
|||
gdk_pixmap_create_from_xpm_d (widget->window,
|
||||
&wilber_mask,
|
||||
&style->bg[GTK_STATE_NORMAL],
|
||||
wilber3_xpm);
|
||||
wilber_xpm);
|
||||
|
||||
gdk_window_set_icon (widget->window, NULL,
|
||||
wilber_pixmap, wilber_mask);
|
||||
|
@ -1100,8 +1100,8 @@ gimp_dialog_new (const gchar *title,
|
|||
gtk_signal_connect (GTK_OBJECT (dialog), "realize",
|
||||
(GtkSignalFunc) gimp_dialog_realize_callback,
|
||||
NULL);
|
||||
*/
|
||||
|
||||
*/
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
|
|
@ -963,7 +963,7 @@ gimp_dialog_delete_callback (GtkWidget *widget,
|
|||
}
|
||||
|
||||
/*
|
||||
#include "/home/mitschel/wilber3.xpm"
|
||||
#include "/home/mitschel/gimpfiles/wilber.xpm"
|
||||
|
||||
static void
|
||||
gimp_dialog_realize_callback (GtkWidget *widget,
|
||||
|
@ -980,7 +980,7 @@ gimp_dialog_realize_callback (GtkWidget *widget,
|
|||
gdk_pixmap_create_from_xpm_d (widget->window,
|
||||
&wilber_mask,
|
||||
&style->bg[GTK_STATE_NORMAL],
|
||||
wilber3_xpm);
|
||||
wilber_xpm);
|
||||
|
||||
gdk_window_set_icon (widget->window, NULL,
|
||||
wilber_pixmap, wilber_mask);
|
||||
|
@ -1100,8 +1100,8 @@ gimp_dialog_new (const gchar *title,
|
|||
gtk_signal_connect (GTK_OBJECT (dialog), "realize",
|
||||
(GtkSignalFunc) gimp_dialog_realize_callback,
|
||||
NULL);
|
||||
*/
|
||||
|
||||
*/
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
|
|
@ -963,7 +963,7 @@ gimp_dialog_delete_callback (GtkWidget *widget,
|
|||
}
|
||||
|
||||
/*
|
||||
#include "/home/mitschel/wilber3.xpm"
|
||||
#include "/home/mitschel/gimpfiles/wilber.xpm"
|
||||
|
||||
static void
|
||||
gimp_dialog_realize_callback (GtkWidget *widget,
|
||||
|
@ -980,7 +980,7 @@ gimp_dialog_realize_callback (GtkWidget *widget,
|
|||
gdk_pixmap_create_from_xpm_d (widget->window,
|
||||
&wilber_mask,
|
||||
&style->bg[GTK_STATE_NORMAL],
|
||||
wilber3_xpm);
|
||||
wilber_xpm);
|
||||
|
||||
gdk_window_set_icon (widget->window, NULL,
|
||||
wilber_pixmap, wilber_mask);
|
||||
|
@ -1100,8 +1100,8 @@ gimp_dialog_new (const gchar *title,
|
|||
gtk_signal_connect (GTK_OBJECT (dialog), "realize",
|
||||
(GtkSignalFunc) gimp_dialog_realize_callback,
|
||||
NULL);
|
||||
*/
|
||||
|
||||
*/
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
|
110
app/tools/crop.c
110
app/tools/crop.c
|
@ -137,7 +137,8 @@ typedef AutoCropType (*ColorsEqualFunc) (guchar *, guchar *, int);
|
|||
|
||||
static void crop_selection_callback (GtkWidget *, gpointer);
|
||||
static void crop_automatic_callback (GtkWidget *, gpointer);
|
||||
static AutoCropType crop_guess_bgcolor (GtkObject *, GetColorFunc, int, int, int, int, guchar *);
|
||||
static AutoCropType crop_guess_bgcolor (GtkObject *, GetColorFunc,
|
||||
int, int, guchar *, int, int, int, int);
|
||||
static int crop_colors_equal (guchar *, guchar *, int);
|
||||
static int crop_colors_alpha (guchar *, guchar *, int);
|
||||
|
||||
|
@ -1085,7 +1086,7 @@ crop_info_create (Tool *tool)
|
|||
(GtkSignalFunc) crop_selection_callback, NULL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Automatic"));
|
||||
button = gtk_button_new_with_label (_("Auto Shrink"));
|
||||
gtk_container_add(GTK_CONTAINER (bbox), button);
|
||||
gtk_signal_connect(GTK_OBJECT (button) , "clicked",
|
||||
(GtkSignalFunc) crop_automatic_callback, NULL);
|
||||
|
@ -1221,8 +1222,8 @@ crop_automatic_callback (GtkWidget *w,
|
|||
guchar bgcolor[4] = {0, 0, 0, 0};
|
||||
gint has_alpha = FALSE;
|
||||
PixelRegion PR;
|
||||
guchar *buffer;
|
||||
gint width, height, bytes;
|
||||
guchar *buffer = NULL;
|
||||
gint offset_x, offset_y, width, height, bytes;
|
||||
gint x, y, abort;
|
||||
gint x1, y1, x2, y2;
|
||||
|
||||
|
@ -1233,35 +1234,42 @@ crop_automatic_callback (GtkWidget *w,
|
|||
draw_core_pause (crop->core, tool);
|
||||
gimp_add_busy_cursors ();
|
||||
|
||||
/* You should always keep in mind that crop->tx2 and crop->ty2 are the NOT the
|
||||
coordinates of the bottomright corner of the area to be cropped. They point
|
||||
at the pixel located one to the right and one to the bottom.
|
||||
*/
|
||||
|
||||
if (crop_options->layer_only)
|
||||
{
|
||||
if (!(active_drawable = gimage_active_drawable (gdisp->gimage)))
|
||||
return;
|
||||
width = drawable_width (GIMP_DRAWABLE (active_drawable));
|
||||
width = drawable_width (GIMP_DRAWABLE (active_drawable));
|
||||
height = drawable_height (GIMP_DRAWABLE (active_drawable));
|
||||
bytes = drawable_bytes (GIMP_DRAWABLE (active_drawable));
|
||||
if (drawable_has_alpha (GIMP_DRAWABLE (active_drawable)))
|
||||
has_alpha = TRUE;
|
||||
get_color_obj = GTK_OBJECT (active_drawable);
|
||||
get_color_func = (GetColorFunc) gimp_drawable_get_color_at;
|
||||
drawable_offsets (GIMP_DRAWABLE (active_drawable), &crop->tx1, &crop->ty1);
|
||||
crop->tx2 = width + crop->tx1;
|
||||
crop->ty2 = height + crop->ty1;
|
||||
drawable_offsets (GIMP_DRAWABLE (active_drawable), &offset_x, &offset_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = gdisp->gimage->width;
|
||||
height = gdisp->gimage->height;
|
||||
has_alpha = TRUE;
|
||||
bytes = gimp_image_composite_bytes (gdisp->gimage);
|
||||
get_color_obj = GTK_OBJECT (gdisp->gimage);
|
||||
get_color_func = (GetColorFunc) gimp_image_get_color_at;
|
||||
bytes = gimp_image_composite_bytes (gdisp->gimage);
|
||||
has_alpha = TRUE;
|
||||
crop->tx1 = crop->ty1 = 0;
|
||||
crop->tx2 = width;
|
||||
crop->ty2 = height;
|
||||
}
|
||||
offset_x = offset_y = 0;
|
||||
}
|
||||
|
||||
switch (crop_guess_bgcolor (get_color_obj, get_color_func, width, height, bytes, has_alpha, bgcolor))
|
||||
x1 = crop->tx1 - offset_x > 0 ? crop->tx1 - offset_x : 0;
|
||||
x2 = crop->tx2 - offset_x < width ? crop->tx2 - offset_x : width;
|
||||
y1 = crop->ty1 - offset_y > 0 ? crop->ty1 - offset_y : 0;
|
||||
y2 = crop->ty2 - offset_y < height ? crop->ty2 - offset_y : height;
|
||||
|
||||
switch (crop_guess_bgcolor (get_color_obj, get_color_func, bytes, has_alpha,
|
||||
bgcolor, x1, x2-1, y1, y2-1))
|
||||
{
|
||||
case AUTO_CROP_ALPHA:
|
||||
colors_equal_func = (ColorsEqualFunc) crop_colors_alpha;
|
||||
|
@ -1273,68 +1281,76 @@ crop_automatic_callback (GtkWidget *w,
|
|||
goto FINISH;
|
||||
}
|
||||
|
||||
width = x2 - x1;
|
||||
height = y2 - y1;
|
||||
|
||||
if (crop_options->layer_only)
|
||||
pixel_region_init (&PR, drawable_data (active_drawable), 0, 0, width, height, FALSE);
|
||||
pixel_region_init (&PR, drawable_data (active_drawable),
|
||||
x1, y1, width, height, FALSE);
|
||||
else
|
||||
pixel_region_init (&PR, gimp_image_composite (gdisp->gimage), 0, 0, width, height, FALSE);
|
||||
pixel_region_init (&PR, gimp_image_composite (gdisp->gimage),
|
||||
x1, y1, width, height, FALSE);
|
||||
|
||||
buffer = g_malloc((width > height ? width : height) * bytes);
|
||||
/* The following could be optimized further by processing the smaller side first
|
||||
instead of defaulting to width --Sven
|
||||
*/
|
||||
|
||||
x1 = x2 = y1 = y2 = 0;
|
||||
buffer = g_malloc ((width > height ? width : height) * bytes);
|
||||
|
||||
/* Check how many of the top lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
for (y = y1; y < y2 && !abort; y++)
|
||||
{
|
||||
pixel_region_get_row (&PR, 0, y, width, buffer, 1);
|
||||
pixel_region_get_row (&PR, x1, y, width, buffer, 1);
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + x * bytes, bytes);
|
||||
}
|
||||
if (y == height && !abort) {
|
||||
g_free (buffer);
|
||||
if (y == y2 && !abort)
|
||||
goto FINISH;
|
||||
}
|
||||
y1 = y - 1;
|
||||
|
||||
/* Check how many of the bottom lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (y = height - 1; y >= y1 && !abort; y--)
|
||||
for (y = y2; y > y1 && !abort; y--)
|
||||
{
|
||||
pixel_region_get_row (&PR, 0, y, width, buffer, 1);
|
||||
pixel_region_get_row (&PR, x1, y-1 , width, buffer, 1);
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + x * bytes, bytes);
|
||||
}
|
||||
y2 = y + 1;
|
||||
|
||||
/* compute a new height for the next operations */
|
||||
height = y2 - y1;
|
||||
|
||||
/* Check how many of the left lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
for (x = x1; x < x2 && !abort; x++)
|
||||
{
|
||||
pixel_region_get_col (&PR, x, y1, y2 - y1 + 1, buffer, 1);
|
||||
for (y = 0; y <= (y2 - y1) && !abort; y++)
|
||||
pixel_region_get_col (&PR, x, y1, height, buffer, 1);
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + y * bytes, bytes);
|
||||
}
|
||||
x1 = x - 1;
|
||||
|
||||
/* Check how many of the right lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (x = width - 1; x >= x1 && !abort; x--)
|
||||
for (x = x2; x > x1 && !abort; x--)
|
||||
{
|
||||
pixel_region_get_col (&PR, x, y1, y2 - y1 + 1, buffer, 1);
|
||||
for (y = 0; y <= (y2 - y1) && !abort; y++)
|
||||
pixel_region_get_col (&PR, x-1, y1, height, buffer, 1);
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + y * bytes, bytes);
|
||||
}
|
||||
x2 = x + 1;
|
||||
|
||||
g_free (buffer);
|
||||
crop->tx1 = offset_x + x1;
|
||||
crop->tx2 = offset_x + x2;
|
||||
crop->ty1 = offset_y + y1;
|
||||
crop->ty2 = offset_y + y2;
|
||||
|
||||
crop->tx2 = crop->tx1 + x2 + 1;
|
||||
crop->ty2 = crop->ty1 + y2 + 1;
|
||||
crop->tx1 += x1;
|
||||
crop->ty1 += y1;
|
||||
crop_recalc (tool, crop);
|
||||
|
||||
FINISH:
|
||||
crop_recalc (tool, crop);
|
||||
g_free (buffer);
|
||||
gimp_remove_busy_cursors (NULL);
|
||||
draw_core_resume (crop->core, tool);
|
||||
|
||||
|
@ -1344,11 +1360,13 @@ crop_automatic_callback (GtkWidget *w,
|
|||
static AutoCropType
|
||||
crop_guess_bgcolor (GtkObject *get_color_obj,
|
||||
GetColorFunc get_color_func,
|
||||
int width,
|
||||
int height,
|
||||
int bytes,
|
||||
int has_alpha,
|
||||
guchar *color)
|
||||
guchar *color,
|
||||
int x1,
|
||||
int x2,
|
||||
int y1,
|
||||
int y2)
|
||||
{
|
||||
guchar *tl = NULL;
|
||||
guchar *tr = NULL;
|
||||
|
@ -1356,20 +1374,20 @@ crop_guess_bgcolor (GtkObject *get_color_obj,
|
|||
guchar *br = NULL;
|
||||
gint i, alpha;
|
||||
|
||||
for (i=0; i< bytes; i++)
|
||||
for (i = 0; i < bytes; i++)
|
||||
color[i] = 0;
|
||||
|
||||
/* First check if there's transparency to crop. If not, guess the
|
||||
* background-color to see if at least 2 corners are equal.
|
||||
*/
|
||||
|
||||
if (!(tl = (*get_color_func) (get_color_obj, 0, 0)))
|
||||
if (!(tl = (*get_color_func) (get_color_obj, x1, y1)))
|
||||
goto ERROR;
|
||||
if (!(tr = (*get_color_func) (get_color_obj, width - 1, 0)))
|
||||
if (!(tr = (*get_color_func) (get_color_obj, x1, y2)))
|
||||
goto ERROR;
|
||||
if (!(bl = (*get_color_func) (get_color_obj, 0, height - 1)))
|
||||
if (!(bl = (*get_color_func) (get_color_obj, x2, y1)))
|
||||
goto ERROR;
|
||||
if (!(br = (*get_color_func) (get_color_obj, width - 1, height - 1)))
|
||||
if (!(br = (*get_color_func) (get_color_obj, x2, y2)))
|
||||
goto ERROR;
|
||||
|
||||
if (has_alpha)
|
||||
|
|
|
@ -137,7 +137,8 @@ typedef AutoCropType (*ColorsEqualFunc) (guchar *, guchar *, int);
|
|||
|
||||
static void crop_selection_callback (GtkWidget *, gpointer);
|
||||
static void crop_automatic_callback (GtkWidget *, gpointer);
|
||||
static AutoCropType crop_guess_bgcolor (GtkObject *, GetColorFunc, int, int, int, int, guchar *);
|
||||
static AutoCropType crop_guess_bgcolor (GtkObject *, GetColorFunc,
|
||||
int, int, guchar *, int, int, int, int);
|
||||
static int crop_colors_equal (guchar *, guchar *, int);
|
||||
static int crop_colors_alpha (guchar *, guchar *, int);
|
||||
|
||||
|
@ -1085,7 +1086,7 @@ crop_info_create (Tool *tool)
|
|||
(GtkSignalFunc) crop_selection_callback, NULL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Automatic"));
|
||||
button = gtk_button_new_with_label (_("Auto Shrink"));
|
||||
gtk_container_add(GTK_CONTAINER (bbox), button);
|
||||
gtk_signal_connect(GTK_OBJECT (button) , "clicked",
|
||||
(GtkSignalFunc) crop_automatic_callback, NULL);
|
||||
|
@ -1221,8 +1222,8 @@ crop_automatic_callback (GtkWidget *w,
|
|||
guchar bgcolor[4] = {0, 0, 0, 0};
|
||||
gint has_alpha = FALSE;
|
||||
PixelRegion PR;
|
||||
guchar *buffer;
|
||||
gint width, height, bytes;
|
||||
guchar *buffer = NULL;
|
||||
gint offset_x, offset_y, width, height, bytes;
|
||||
gint x, y, abort;
|
||||
gint x1, y1, x2, y2;
|
||||
|
||||
|
@ -1233,35 +1234,42 @@ crop_automatic_callback (GtkWidget *w,
|
|||
draw_core_pause (crop->core, tool);
|
||||
gimp_add_busy_cursors ();
|
||||
|
||||
/* You should always keep in mind that crop->tx2 and crop->ty2 are the NOT the
|
||||
coordinates of the bottomright corner of the area to be cropped. They point
|
||||
at the pixel located one to the right and one to the bottom.
|
||||
*/
|
||||
|
||||
if (crop_options->layer_only)
|
||||
{
|
||||
if (!(active_drawable = gimage_active_drawable (gdisp->gimage)))
|
||||
return;
|
||||
width = drawable_width (GIMP_DRAWABLE (active_drawable));
|
||||
width = drawable_width (GIMP_DRAWABLE (active_drawable));
|
||||
height = drawable_height (GIMP_DRAWABLE (active_drawable));
|
||||
bytes = drawable_bytes (GIMP_DRAWABLE (active_drawable));
|
||||
if (drawable_has_alpha (GIMP_DRAWABLE (active_drawable)))
|
||||
has_alpha = TRUE;
|
||||
get_color_obj = GTK_OBJECT (active_drawable);
|
||||
get_color_func = (GetColorFunc) gimp_drawable_get_color_at;
|
||||
drawable_offsets (GIMP_DRAWABLE (active_drawable), &crop->tx1, &crop->ty1);
|
||||
crop->tx2 = width + crop->tx1;
|
||||
crop->ty2 = height + crop->ty1;
|
||||
drawable_offsets (GIMP_DRAWABLE (active_drawable), &offset_x, &offset_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = gdisp->gimage->width;
|
||||
height = gdisp->gimage->height;
|
||||
has_alpha = TRUE;
|
||||
bytes = gimp_image_composite_bytes (gdisp->gimage);
|
||||
get_color_obj = GTK_OBJECT (gdisp->gimage);
|
||||
get_color_func = (GetColorFunc) gimp_image_get_color_at;
|
||||
bytes = gimp_image_composite_bytes (gdisp->gimage);
|
||||
has_alpha = TRUE;
|
||||
crop->tx1 = crop->ty1 = 0;
|
||||
crop->tx2 = width;
|
||||
crop->ty2 = height;
|
||||
}
|
||||
offset_x = offset_y = 0;
|
||||
}
|
||||
|
||||
switch (crop_guess_bgcolor (get_color_obj, get_color_func, width, height, bytes, has_alpha, bgcolor))
|
||||
x1 = crop->tx1 - offset_x > 0 ? crop->tx1 - offset_x : 0;
|
||||
x2 = crop->tx2 - offset_x < width ? crop->tx2 - offset_x : width;
|
||||
y1 = crop->ty1 - offset_y > 0 ? crop->ty1 - offset_y : 0;
|
||||
y2 = crop->ty2 - offset_y < height ? crop->ty2 - offset_y : height;
|
||||
|
||||
switch (crop_guess_bgcolor (get_color_obj, get_color_func, bytes, has_alpha,
|
||||
bgcolor, x1, x2-1, y1, y2-1))
|
||||
{
|
||||
case AUTO_CROP_ALPHA:
|
||||
colors_equal_func = (ColorsEqualFunc) crop_colors_alpha;
|
||||
|
@ -1273,68 +1281,76 @@ crop_automatic_callback (GtkWidget *w,
|
|||
goto FINISH;
|
||||
}
|
||||
|
||||
width = x2 - x1;
|
||||
height = y2 - y1;
|
||||
|
||||
if (crop_options->layer_only)
|
||||
pixel_region_init (&PR, drawable_data (active_drawable), 0, 0, width, height, FALSE);
|
||||
pixel_region_init (&PR, drawable_data (active_drawable),
|
||||
x1, y1, width, height, FALSE);
|
||||
else
|
||||
pixel_region_init (&PR, gimp_image_composite (gdisp->gimage), 0, 0, width, height, FALSE);
|
||||
pixel_region_init (&PR, gimp_image_composite (gdisp->gimage),
|
||||
x1, y1, width, height, FALSE);
|
||||
|
||||
buffer = g_malloc((width > height ? width : height) * bytes);
|
||||
/* The following could be optimized further by processing the smaller side first
|
||||
instead of defaulting to width --Sven
|
||||
*/
|
||||
|
||||
x1 = x2 = y1 = y2 = 0;
|
||||
buffer = g_malloc ((width > height ? width : height) * bytes);
|
||||
|
||||
/* Check how many of the top lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
for (y = y1; y < y2 && !abort; y++)
|
||||
{
|
||||
pixel_region_get_row (&PR, 0, y, width, buffer, 1);
|
||||
pixel_region_get_row (&PR, x1, y, width, buffer, 1);
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + x * bytes, bytes);
|
||||
}
|
||||
if (y == height && !abort) {
|
||||
g_free (buffer);
|
||||
if (y == y2 && !abort)
|
||||
goto FINISH;
|
||||
}
|
||||
y1 = y - 1;
|
||||
|
||||
/* Check how many of the bottom lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (y = height - 1; y >= y1 && !abort; y--)
|
||||
for (y = y2; y > y1 && !abort; y--)
|
||||
{
|
||||
pixel_region_get_row (&PR, 0, y, width, buffer, 1);
|
||||
pixel_region_get_row (&PR, x1, y-1 , width, buffer, 1);
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + x * bytes, bytes);
|
||||
}
|
||||
y2 = y + 1;
|
||||
|
||||
/* compute a new height for the next operations */
|
||||
height = y2 - y1;
|
||||
|
||||
/* Check how many of the left lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (x = 0; x < width && !abort; x++)
|
||||
for (x = x1; x < x2 && !abort; x++)
|
||||
{
|
||||
pixel_region_get_col (&PR, x, y1, y2 - y1 + 1, buffer, 1);
|
||||
for (y = 0; y <= (y2 - y1) && !abort; y++)
|
||||
pixel_region_get_col (&PR, x, y1, height, buffer, 1);
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + y * bytes, bytes);
|
||||
}
|
||||
x1 = x - 1;
|
||||
|
||||
/* Check how many of the right lines are uniform/transparent. */
|
||||
abort = FALSE;
|
||||
for (x = width - 1; x >= x1 && !abort; x--)
|
||||
for (x = x2; x > x1 && !abort; x--)
|
||||
{
|
||||
pixel_region_get_col (&PR, x, y1, y2 - y1 + 1, buffer, 1);
|
||||
for (y = 0; y <= (y2 - y1) && !abort; y++)
|
||||
pixel_region_get_col (&PR, x-1, y1, height, buffer, 1);
|
||||
for (y = 0; y < height && !abort; y++)
|
||||
abort = !(colors_equal_func) (bgcolor, buffer + y * bytes, bytes);
|
||||
}
|
||||
x2 = x + 1;
|
||||
|
||||
g_free (buffer);
|
||||
crop->tx1 = offset_x + x1;
|
||||
crop->tx2 = offset_x + x2;
|
||||
crop->ty1 = offset_y + y1;
|
||||
crop->ty2 = offset_y + y2;
|
||||
|
||||
crop->tx2 = crop->tx1 + x2 + 1;
|
||||
crop->ty2 = crop->ty1 + y2 + 1;
|
||||
crop->tx1 += x1;
|
||||
crop->ty1 += y1;
|
||||
crop_recalc (tool, crop);
|
||||
|
||||
FINISH:
|
||||
crop_recalc (tool, crop);
|
||||
g_free (buffer);
|
||||
gimp_remove_busy_cursors (NULL);
|
||||
draw_core_resume (crop->core, tool);
|
||||
|
||||
|
@ -1344,11 +1360,13 @@ crop_automatic_callback (GtkWidget *w,
|
|||
static AutoCropType
|
||||
crop_guess_bgcolor (GtkObject *get_color_obj,
|
||||
GetColorFunc get_color_func,
|
||||
int width,
|
||||
int height,
|
||||
int bytes,
|
||||
int has_alpha,
|
||||
guchar *color)
|
||||
guchar *color,
|
||||
int x1,
|
||||
int x2,
|
||||
int y1,
|
||||
int y2)
|
||||
{
|
||||
guchar *tl = NULL;
|
||||
guchar *tr = NULL;
|
||||
|
@ -1356,20 +1374,20 @@ crop_guess_bgcolor (GtkObject *get_color_obj,
|
|||
guchar *br = NULL;
|
||||
gint i, alpha;
|
||||
|
||||
for (i=0; i< bytes; i++)
|
||||
for (i = 0; i < bytes; i++)
|
||||
color[i] = 0;
|
||||
|
||||
/* First check if there's transparency to crop. If not, guess the
|
||||
* background-color to see if at least 2 corners are equal.
|
||||
*/
|
||||
|
||||
if (!(tl = (*get_color_func) (get_color_obj, 0, 0)))
|
||||
if (!(tl = (*get_color_func) (get_color_obj, x1, y1)))
|
||||
goto ERROR;
|
||||
if (!(tr = (*get_color_func) (get_color_obj, width - 1, 0)))
|
||||
if (!(tr = (*get_color_func) (get_color_obj, x1, y2)))
|
||||
goto ERROR;
|
||||
if (!(bl = (*get_color_func) (get_color_obj, 0, height - 1)))
|
||||
if (!(bl = (*get_color_func) (get_color_obj, x2, y1)))
|
||||
goto ERROR;
|
||||
if (!(br = (*get_color_func) (get_color_obj, width - 1, height - 1)))
|
||||
if (!(br = (*get_color_func) (get_color_obj, x2, y2)))
|
||||
goto ERROR;
|
||||
|
||||
if (has_alpha)
|
||||
|
|
|
@ -85,6 +85,7 @@ static char *doc_not_found_format_string =
|
|||
"<html><head><title>Document not found</title></head>"
|
||||
"<body bgcolor=\"#ffffff\">"
|
||||
"<center>"
|
||||
"<p>"
|
||||
"%s"
|
||||
"<h2>Couldn't find document</h2>"
|
||||
"%s"
|
||||
|
@ -96,6 +97,7 @@ static char *dir_not_found_format_string =
|
|||
"<html><head><title>Directory not found</title></head>"
|
||||
"<body bgcolor=\"#ffffff\">"
|
||||
"<center>"
|
||||
"<p>"
|
||||
"%s"
|
||||
"<h2>Couldn't change to directory</h2>"
|
||||
"%s"
|
||||
|
@ -143,7 +145,7 @@ static GtkWidget *forward_button;
|
|||
static GtkWidget *notebook;
|
||||
static GtkWidget *combo;
|
||||
|
||||
static gchar *eek_png_tag = "<h1>Eeek!</h1>\n";
|
||||
static gchar *eek_png_tag = "<h1>Eeek!</h1>";
|
||||
|
||||
/* GIMP plugin stuff */
|
||||
|
||||
|
@ -662,14 +664,15 @@ open_browser_dialog (gchar *path)
|
|||
|
||||
if (chdir (root_dir) == -1)
|
||||
{
|
||||
g_warning ("Couldn't find my root html directory.");
|
||||
gimp_message ("GIMP Help Browser Error.\n\n"
|
||||
"Couldn't find my root html directory.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
eek_png_path = g_strconcat (root_dir, G_DIR_SEPARATOR_S,
|
||||
"eek.png", NULL);
|
||||
if (access (eek_png_path, R_OK) == 0)
|
||||
eek_png_tag = g_strdup_printf ("<img src=\"%s\">\n", eek_png_path);
|
||||
eek_png_tag = g_strdup_printf ("<img src=\"%s\">", eek_png_path);
|
||||
|
||||
g_free (eek_png_path);
|
||||
g_free (root_dir);
|
||||
|
|
Loading…
Reference in New Issue