diff --git a/ChangeLog b/ChangeLog index e2afcef4c6..2c69102b2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2003-11-11 Sven Neumann + + * app/display/Makefile.am + * app/display/gimpdisplayshell-marching-ants.h: removed this file. + + * app/display/gimpcanvas.[ch]: generalized creation of GCs. Added + styles for drawing the selection and layer boundaries. Also added + support for changing stipple masks as was used by an older + implementation of the marching ants (see below). + + * app/display/gimpdisplayshell-callbacks.c + * app/display/gimpdisplayshell.c: don't create the Selection when + the canvas is realized but only once when it is created. + + * app/display/gimpdisplayshell-selection.[ch]: removed all GC code + and draw by means of GimpCanvas. Also resurrected a different + implementation of the marching ants that was lost since 1.2 + (#undef USE_DRAWPOINTS). + 2003-11-11 Michael Natterer * app/display/gimpdisplayshell-appearance.c: update diff --git a/app/display/Makefile.am b/app/display/Makefile.am index a981a4c14f..b0857acf02 100644 --- a/app/display/Makefile.am +++ b/app/display/Makefile.am @@ -46,7 +46,6 @@ libappdisplay_a_sources = \ gimpdisplayshell-filter-dialog.h \ gimpdisplayshell-layer-select.c \ gimpdisplayshell-layer-select.h \ - gimpdisplayshell-marching-ants.h \ gimpdisplayshell-render.c \ gimpdisplayshell-render.h \ gimpdisplayshell-scale.c \ diff --git a/app/display/gimpcanvas.c b/app/display/gimpcanvas.c index 82b2010bf6..20b45a6f98 100644 --- a/app/display/gimpcanvas.c +++ b/app/display/gimpcanvas.c @@ -29,21 +29,100 @@ /* local function prototypes */ -static void gimp_canvas_class_init (GimpCanvasClass *klass); -static void gimp_canvas_init (GimpCanvas *gdisp); -static void gimp_canvas_realize (GtkWidget *widget); -static void gimp_canvas_unrealize (GtkWidget *widget); - -static GdkGC * gimp_canvas_gc_new (GtkWidget *widget, - GimpCanvasStyle style); -static GdkGC * gimp_canvas_guides_gc_new (GtkWidget *widget, - GimpOrientationType orientation, - GdkColor *fg, - GdkColor *bg); +static void gimp_canvas_class_init (GimpCanvasClass *klass); +static void gimp_canvas_init (GimpCanvas *gdisp); +static void gimp_canvas_realize (GtkWidget *widget); +static void gimp_canvas_unrealize (GtkWidget *widget); +static GdkGC * gimp_canvas_gc_new (GimpCanvas *canvas, + GimpCanvasStyle style); static GtkDrawingAreaClass *parent_class = NULL; +static const guchar stipples[GIMP_CANVAS_NUM_STIPPLES][8] = +{ + { + 0xF0, /* ####---- */ + 0xE1, /* ###----# */ + 0xC3, /* ##----## */ + 0x87, /* #----### */ + 0x0F, /* ----#### */ + 0x1E, /* ---####- */ + 0x3C, /* --####-- */ + 0x78, /* -####--- */ + }, + { + 0xE1, /* ###----# */ + 0xC3, /* ##----## */ + 0x87, /* #----### */ + 0x0F, /* ----#### */ + 0x1E, /* ---####- */ + 0x3C, /* --####-- */ + 0x78, /* -####--- */ + 0xF0, /* ####---- */ + }, + { + 0xC3, /* ##----## */ + 0x87, /* #----### */ + 0x0F, /* ----#### */ + 0x1E, /* ---####- */ + 0x3C, /* --####-- */ + 0x78, /* -####--- */ + 0xF0, /* ####---- */ + 0xE1, /* ###----# */ + }, + { + 0x87, /* #----### */ + 0x0F, /* ----#### */ + 0x1E, /* ---####- */ + 0x3C, /* --####-- */ + 0x78, /* -####--- */ + 0xF0, /* ####---- */ + 0xE1, /* ###----# */ + 0xC3, /* ##----## */ + }, + { + 0x0F, /* ----#### */ + 0x1E, /* ---####- */ + 0x3C, /* --####-- */ + 0x78, /* -####--- */ + 0xF0, /* ####---- */ + 0xE1, /* ###----# */ + 0xC3, /* ##----## */ + 0x87, /* #----### */ + }, + { + 0x1E, /* ---####- */ + 0x3C, /* --####-- */ + 0x78, /* -####--- */ + 0xF0, /* ####---- */ + 0xE1, /* ###----# */ + 0xC3, /* ##----## */ + 0x87, /* #----### */ + 0x0F, /* ----#### */ + }, + { + 0x3C, /* --####-- */ + 0x78, /* -####--- */ + 0xF0, /* ####---- */ + 0xE1, /* ###----# */ + 0xC3, /* ##----## */ + 0x87, /* #----### */ + 0x0F, /* ----#### */ + 0x1E, /* ---####- */ + }, + { + 0x78, /* -####--- */ + 0xF0, /* ####---- */ + 0xE1, /* ###----# */ + 0xC3, /* ##----## */ + 0x87, /* #----### */ + 0x0F, /* ----#### */ + 0x1E, /* ---####- */ + 0x3C, /* --####-- */ + }, +}; + GType gimp_canvas_get_type (void) @@ -91,6 +170,9 @@ gimp_canvas_init (GimpCanvas *canvas) for (i = 0; i < GIMP_CANVAS_NUM_STYLES; i++) canvas->gc[i] = NULL; + + for (i = 0; i < GIMP_CANVAS_NUM_STIPPLES; i++) + canvas->stipple[i] = NULL; } static void @@ -100,8 +182,9 @@ gimp_canvas_realize (GtkWidget *widget) GTK_WIDGET_CLASS (parent_class)->realize (widget); - canvas->gc[GIMP_CANVAS_STYLE_RENDER] = - gimp_canvas_gc_new (widget, GIMP_CANVAS_STYLE_RENDER); + canvas->stipple[0] = + gdk_bitmap_create_from_data (widget->window, + (const gchar *) stipples[0], 8, 8); } static void @@ -119,27 +202,119 @@ gimp_canvas_unrealize (GtkWidget *widget) } } + for (i = 0; i < GIMP_CANVAS_NUM_STIPPLES; i++) + { + if (canvas->stipple[i]) + { + g_object_unref (canvas->stipple[i]); + canvas->stipple[i] = NULL; + } + } + GTK_WIDGET_CLASS (parent_class)->unrealize (widget); } static GdkGC * -gimp_canvas_gc_new (GtkWidget *widget, +gimp_canvas_gc_new (GimpCanvas *canvas, GimpCanvasStyle style) { - GdkGC *gc = NULL; - GdkColor fg; - GdkColor bg; + GtkWidget *widget = GTK_WIDGET (canvas); + GdkGC *gc; + GdkGCValues values; + GdkGCValuesMask mask = 0; + GdkColor fg; + GdkColor bg; switch (style) { - case GIMP_CANVAS_STYLE_XOR: - case GIMP_CANVAS_STYLE_XOR_DASHED: - fg.pixel = 0xFFFFFFFF; - bg.pixel = 0x00000000; + case GIMP_CANVAS_STYLE_BLACK: + case GIMP_CANVAS_STYLE_WHITE: break; - case GIMP_CANVAS_STYLE_HGUIDE_NORMAL: - case GIMP_CANVAS_STYLE_VGUIDE_NORMAL: + case GIMP_CANVAS_STYLE_RENDER: + mask |= GDK_GC_EXPOSURES; + values.graphics_exposures = TRUE; + break; + + case GIMP_CANVAS_STYLE_XOR_DASHED: + mask |= GDK_GC_LINE_STYLE; + values.line_style = GDK_LINE_ON_OFF_DASH; + /* fallthrough */ + + case GIMP_CANVAS_STYLE_XOR: + mask |= GDK_GC_FUNCTION; + values.function = GDK_INVERT; + break; + + case GIMP_CANVAS_STYLE_SELECTION_IN: + case GIMP_CANVAS_STYLE_SELECTION_OUT: + case GIMP_CANVAS_STYLE_LAYER_BOUNDARY: + mask |= GDK_GC_CAP_STYLE; + values.cap_style = GDK_CAP_BUTT; + /* fallthrough */ + + case GIMP_CANVAS_STYLE_GUIDE_NORMAL: + case GIMP_CANVAS_STYLE_GUIDE_ACTIVE: + mask |= GDK_GC_FILL | GDK_GC_STIPPLE; + values.fill = GDK_OPAQUE_STIPPLED; + values.stipple = canvas->stipple[0]; + break; + + case GIMP_CANVAS_STYLE_CUSTOM: + default: + g_assert_not_reached (); + break; + } + + gc = gdk_gc_new_with_values (widget->window, &values, mask); + + switch (style) + { + default: + case GIMP_CANVAS_STYLE_WHITE: + case GIMP_CANVAS_STYLE_XOR: + case GIMP_CANVAS_STYLE_XOR_DASHED: + fg.red = 0xffff; + fg.green = 0xffff; + fg.blue = 0xffff; + + bg.red = 0x0; + bg.green = 0x0; + bg.blue = 0x0; + break; + + case GIMP_CANVAS_STYLE_BLACK: + case GIMP_CANVAS_STYLE_SELECTION_IN: + fg.red = 0x0; + fg.green = 0x0; + fg.blue = 0x0; + + bg.red = 0xffff; + bg.green = 0xffff; + bg.blue = 0xffff; + break; + + case GIMP_CANVAS_STYLE_SELECTION_OUT: + fg.red = 0xffff; + fg.green = 0xffff; + fg.blue = 0xffff; + + bg.red = 0x7f7f; + bg.green = 0x7f7f; + bg.blue = 0x7f7f; + break; + + case GIMP_CANVAS_STYLE_LAYER_BOUNDARY: + fg.red = 0x0; + fg.green = 0x0; + fg.blue = 0x0; + + bg.red = 0xffff; + bg.green = 0xffff; + bg.blue = 0x0; + break; + + case GIMP_CANVAS_STYLE_GUIDE_NORMAL: fg.red = 0x0; fg.green = 0x0; fg.blue = 0x0; @@ -149,8 +324,7 @@ gimp_canvas_gc_new (GtkWidget *widget, bg.blue = 0xffff; break; - case GIMP_CANVAS_STYLE_HGUIDE_ACTIVE: - case GIMP_CANVAS_STYLE_VGUIDE_ACTIVE: + case GIMP_CANVAS_STYLE_GUIDE_ACTIVE: fg.red = 0x0; fg.green = 0x0; fg.blue = 0x0; @@ -159,88 +333,10 @@ gimp_canvas_gc_new (GtkWidget *widget, bg.green = 0x0; bg.blue = 0x0; break; - - default: - break; } - switch (style) - { - case GIMP_CANVAS_STYLE_RENDER: - gc = gdk_gc_new (widget->window); - gdk_gc_set_exposures (gc, TRUE); - break; - - case GIMP_CANVAS_STYLE_XOR: - case GIMP_CANVAS_STYLE_XOR_DASHED: - gc = gdk_gc_new (widget->window); - gdk_gc_set_function (gc, GDK_INVERT); - gdk_gc_set_foreground (gc, &fg); - gdk_gc_set_background (gc, &bg); - gdk_gc_set_line_attributes (gc, - 0, - (style == GIMP_CANVAS_STYLE_XOR ? - GDK_LINE_SOLID : GDK_LINE_ON_OFF_DASH), - GDK_CAP_NOT_LAST, - GDK_JOIN_MITER); - break; - - case GIMP_CANVAS_STYLE_HGUIDE_NORMAL: - case GIMP_CANVAS_STYLE_HGUIDE_ACTIVE: - gc = gimp_canvas_guides_gc_new (widget, - GIMP_ORIENTATION_HORIZONTAL, &fg, &bg); - break; - - case GIMP_CANVAS_STYLE_VGUIDE_NORMAL: - case GIMP_CANVAS_STYLE_VGUIDE_ACTIVE: - gc = gimp_canvas_guides_gc_new (widget, - GIMP_ORIENTATION_VERTICAL, &fg, &bg); - break; - - case GIMP_CANVAS_STYLE_CUSTOM: - g_assert_not_reached (); - break; - - default: - break; - } - - return gc; -} - -static GdkGC * -gimp_canvas_guides_gc_new (GtkWidget *widget, - GimpOrientationType orient, - GdkColor *fg, - GdkColor *bg) -{ - const guchar stipple[] = - { - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - 0x87, /* #----### */ - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - }; - - GdkGC *gc; - GdkGCValues values; - - values.fill = GDK_OPAQUE_STIPPLED; - values.stipple = - gdk_bitmap_create_from_data (widget->window, - (const gchar *) stipple, - orient == GIMP_ORIENTATION_HORIZONTAL ? 8 : 1, - orient == GIMP_ORIENTATION_VERTICAL ? 8 : 1); - - gc = gdk_gc_new_with_values (widget->window, - &values, GDK_GC_FILL | GDK_GC_STIPPLE); - - gdk_gc_set_rgb_fg_color (gc, fg); - gdk_gc_set_rgb_bg_color (gc, bg); + gdk_gc_set_rgb_fg_color (gc, &fg); + gdk_gc_set_rgb_bg_color (gc, &bg); return gc; } @@ -261,20 +357,29 @@ gimp_canvas_draw_cursor (GimpCanvas *canvas, gint x, gint y) { - GtkWidget *widget = GTK_WIDGET (canvas); + GtkWidget *widget = GTK_WIDGET (canvas); + GimpCanvasStyle style; - gdk_draw_line (widget->window, - widget->style->white_gc, x - 7, y - 1, x + 7, y - 1); - gdk_draw_line (widget->window, - widget->style->black_gc, x - 7, y, x + 7, y ); - gdk_draw_line (widget->window, - widget->style->white_gc, x - 7, y + 1, x + 7, y + 1); - gdk_draw_line (widget->window, - widget->style->white_gc, x - 1, y - 7, x - 1, y + 7); - gdk_draw_line (widget->window, - widget->style->black_gc, x, y - 7, x, y + 7); - gdk_draw_line (widget->window, - widget->style->white_gc, x + 1, y - 7, x + 1, y + 7); + for (style = GIMP_CANVAS_STYLE_BLACK; + style <= GIMP_CANVAS_STYLE_WHITE; + style++) + { + if (! canvas->gc[style]) + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); + } + + gdk_draw_line (widget->window, canvas->gc[GIMP_CANVAS_STYLE_WHITE], + x - 7, y - 1, x + 7, y - 1); + gdk_draw_line (widget->window, canvas->gc[GIMP_CANVAS_STYLE_BLACK], + x - 7, y, x + 7, y ); + gdk_draw_line (widget->window, canvas->gc[GIMP_CANVAS_STYLE_WHITE], + x - 7, y + 1, x + 7, y + 1); + gdk_draw_line (widget->window, canvas->gc[GIMP_CANVAS_STYLE_WHITE], + x - 1, y - 7, x - 1, y + 7); + gdk_draw_line (widget->window, canvas->gc[GIMP_CANVAS_STYLE_BLACK], + x, y - 7, x, y + 7); + gdk_draw_line (widget->window, canvas->gc[GIMP_CANVAS_STYLE_WHITE], + x + 1, y - 7, x + 1, y + 7); } void @@ -286,11 +391,25 @@ gimp_canvas_draw_point (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_point (widget->window, canvas->gc[style], x, y); } +void +gimp_canvas_draw_points (GimpCanvas *canvas, + GimpCanvasStyle style, + GdkPoint *points, + gint num_points) +{ + GtkWidget *widget = GTK_WIDGET (canvas); + + if (! canvas->gc[style]) + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); + + gdk_draw_points (widget->window, canvas->gc[style], points, num_points); +} + void gimp_canvas_draw_line (GimpCanvas *canvas, GimpCanvasStyle style, @@ -302,7 +421,7 @@ gimp_canvas_draw_line (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_line (widget->window, canvas->gc[style], x1, y1, x2, y2); } @@ -316,7 +435,7 @@ gimp_canvas_draw_lines (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_lines (widget->window, canvas->gc[style], points, num_points); } @@ -333,7 +452,7 @@ gimp_canvas_draw_rectangle (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_rectangle (widget->window, canvas->gc[style], filled, x, y, width, height); @@ -353,7 +472,7 @@ gimp_canvas_draw_arc (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_arc (widget->window, canvas->gc[style], filled, x, y, width, height, angle1, angle2); @@ -369,7 +488,7 @@ gimp_canvas_draw_polygon (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_polygon (widget->window, canvas->gc[style], filled, points, num_points); @@ -384,7 +503,7 @@ gimp_canvas_draw_segments (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_segments (widget->window, canvas->gc[style], segments, num_segments); @@ -405,7 +524,7 @@ gimp_canvas_draw_rgb (GimpCanvas *canvas, GtkWidget *widget = GTK_WIDGET (canvas); if (! canvas->gc[style]) - canvas->gc[style] = gimp_canvas_gc_new (widget, style); + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); gdk_draw_rgb_image_dithalign (widget->window, canvas->gc[style], x, y, width, height, @@ -413,6 +532,57 @@ gimp_canvas_draw_rgb (GimpCanvas *canvas, rgb_buf, rowstride, xdith, ydith); } +void +gimp_canvas_set_clip_rect (GimpCanvas *canvas, + GimpCanvasStyle style, + GdkRectangle *rect) +{ + if (! canvas->gc[style]) + { + if (! rect) + return; + + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); + } + + gdk_gc_set_clip_rectangle (canvas->gc[style], rect); +} + +void +gimp_canvas_set_stipple_index (GimpCanvas *canvas, + GimpCanvasStyle style, + guint index) +{ + if (! canvas->gc[style]) + canvas->gc[style] = gimp_canvas_gc_new (canvas, style); + + index = index % GIMP_CANVAS_NUM_STIPPLES; + + if (! canvas->stipple[index]) + { + GtkWidget *widget = GTK_WIDGET (canvas); + + canvas->stipple[index] = + gdk_bitmap_create_from_data (widget->window, + (const gchar *) stipples[index], 8, 8); + } + + gdk_gc_set_stipple (canvas->gc[style], canvas->stipple[index]); +} + +void +gimp_canvas_set_custom_gc (GimpCanvas *canvas, + GdkGC *gc) +{ + if (canvas->gc[GIMP_CANVAS_STYLE_CUSTOM]) + g_object_unref (canvas->gc[GIMP_CANVAS_STYLE_CUSTOM]); + + canvas->gc[GIMP_CANVAS_STYLE_CUSTOM] = gc; + + if (gc) + g_object_ref (gc); +} + void gimp_canvas_set_bg_color (GimpCanvas *canvas, GimpRGB *color) @@ -432,16 +602,3 @@ gimp_canvas_set_bg_color (GimpCanvas *canvas, gdk_window_set_background (widget->window, &gdk_color); } - -void -gimp_canvas_set_custom_gc (GimpCanvas *canvas, - GdkGC *gc) -{ - if (canvas->gc[GIMP_CANVAS_STYLE_CUSTOM]) - g_object_unref (canvas->gc[GIMP_CANVAS_STYLE_CUSTOM]); - - canvas->gc[GIMP_CANVAS_STYLE_CUSTOM] = gc; - - if (gc) - g_object_ref (gc); -} diff --git a/app/display/gimpcanvas.h b/app/display/gimpcanvas.h index f894b2085c..12ae29d826 100644 --- a/app/display/gimpcanvas.h +++ b/app/display/gimpcanvas.h @@ -25,18 +25,24 @@ typedef enum { + GIMP_CANVAS_STYLE_BLACK, + GIMP_CANVAS_STYLE_WHITE, GIMP_CANVAS_STYLE_RENDER, GIMP_CANVAS_STYLE_XOR, GIMP_CANVAS_STYLE_XOR_DASHED, - GIMP_CANVAS_STYLE_HGUIDE_NORMAL, - GIMP_CANVAS_STYLE_HGUIDE_ACTIVE, - GIMP_CANVAS_STYLE_VGUIDE_NORMAL, - GIMP_CANVAS_STYLE_VGUIDE_ACTIVE, + GIMP_CANVAS_STYLE_SELECTION_IN, + GIMP_CANVAS_STYLE_SELECTION_OUT, + GIMP_CANVAS_STYLE_LAYER_BOUNDARY, + GIMP_CANVAS_STYLE_GUIDE_NORMAL, + GIMP_CANVAS_STYLE_GUIDE_ACTIVE, GIMP_CANVAS_STYLE_CUSTOM, GIMP_CANVAS_NUM_STYLES } GimpCanvasStyle; +#define GIMP_CANVAS_NUM_STIPPLES 8 + + #define GIMP_TYPE_CANVAS (gimp_canvas_get_type ()) #define GIMP_CANVAS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CANVAS, GimpCanvas)) #define GIMP_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CANVAS, GimpCanvasClass)) @@ -52,6 +58,7 @@ struct _GimpCanvas GtkDrawingArea parent_instance; GdkGC *gc[GIMP_CANVAS_NUM_STYLES]; + GdkBitmap *stipple[GIMP_CANVAS_NUM_STIPPLES]; }; struct _GimpCanvasClass @@ -60,68 +67,77 @@ struct _GimpCanvasClass }; -GType gimp_canvas_get_type (void) G_GNUC_CONST; +GType gimp_canvas_get_type (void) G_GNUC_CONST; -GtkWidget * gimp_canvas_new (void); +GtkWidget * gimp_canvas_new (void); -void gimp_canvas_draw_cursor (GimpCanvas *canvas, - gint x, - gint y); -void gimp_canvas_draw_point (GimpCanvas *canvas, - GimpCanvasStyle style, - gint x, - gint y); -void gimp_canvas_draw_line (GimpCanvas *canvas, - GimpCanvasStyle style, - gint x1, - gint y1, - gint x2, - gint y2); -void gimp_canvas_draw_lines (GimpCanvas *canvas, - GimpCanvasStyle style, - GdkPoint *points, - gint num_points); -void gimp_canvas_draw_rectangle (GimpCanvas *canvas, - GimpCanvasStyle style, - gboolean filled, - gint x, - gint y, - gint width, - gint height); -void gimp_canvas_draw_arc (GimpCanvas *canvas, - GimpCanvasStyle style, - gboolean filled, - gint x, - gint y, - gint width, - gint height, - gint angle1, - gint angle2); -void gimp_canvas_draw_polygon (GimpCanvas *canvas, - GimpCanvasStyle style, - gboolean filled, - GdkPoint *points, - gint num_points); -void gimp_canvas_draw_segments (GimpCanvas *canvas, - GimpCanvasStyle style, - GdkSegment *segments, - gint num_segments); -void gimp_canvas_draw_rgb (GimpCanvas *canvas, - GimpCanvasStyle style, - gint x, - gint y, - gint width, - gint height, - guchar *rgb_buf, - gint rowstride, - gint xdith, - gint ydith); +void gimp_canvas_draw_cursor (GimpCanvas *canvas, + gint x, + gint y); +void gimp_canvas_draw_point (GimpCanvas *canvas, + GimpCanvasStyle style, + gint x, + gint y); +void gimp_canvas_draw_points (GimpCanvas *canvas, + GimpCanvasStyle style, + GdkPoint *points, + gint num_points); +void gimp_canvas_draw_line (GimpCanvas *canvas, + GimpCanvasStyle style, + gint x1, + gint y1, + gint x2, + gint y2); +void gimp_canvas_draw_lines (GimpCanvas *canvas, + GimpCanvasStyle style, + GdkPoint *points, + gint num_points); +void gimp_canvas_draw_rectangle (GimpCanvas *canvas, + GimpCanvasStyle style, + gboolean filled, + gint x, + gint y, + gint width, + gint height); +void gimp_canvas_draw_arc (GimpCanvas *canvas, + GimpCanvasStyle style, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); +void gimp_canvas_draw_polygon (GimpCanvas *canvas, + GimpCanvasStyle style, + gboolean filled, + GdkPoint *points, + gint num_points); +void gimp_canvas_draw_segments (GimpCanvas *canvas, + GimpCanvasStyle style, + GdkSegment *segments, + gint num_segments); +void gimp_canvas_draw_rgb (GimpCanvas *canvas, + GimpCanvasStyle style, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride, + gint xdith, + gint ydith); -void gimp_canvas_set_bg_color (GimpCanvas *canvas, - GimpRGB *color); - -void gimp_canvas_set_custom_gc (GimpCanvas *canvas, - GdkGC *gc); +void gimp_canvas_set_clip_rect (GimpCanvas *canvas, + GimpCanvasStyle style, + GdkRectangle *rect); +void gimp_canvas_set_stipple_index (GimpCanvas *canvas, + GimpCanvasStyle style, + guint index); +void gimp_canvas_set_custom_gc (GimpCanvas *canvas, + GdkGC *gc); +void gimp_canvas_set_bg_color (GimpCanvas *canvas, + GimpRGB *color); #endif /* __GIMP_CANVAS_H__ */ diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c index e4624d3d42..9dc6b117d1 100644 --- a/app/display/gimpdisplayshell-callbacks.c +++ b/app/display/gimpdisplayshell-callbacks.c @@ -267,12 +267,6 @@ gimp_display_shell_canvas_realize (GtkWidget *canvas, gimp_display_shell_update_title (shell); - /* create the selection object */ - shell->select = gimp_display_shell_selection_create (canvas->window, - shell, - gdisp->gimage->height, - gdisp->gimage->width); - shell->disp_width = canvas->allocation.width; shell->disp_height = canvas->allocation.height; diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c index b50c4ef2b3..ceaf1a2931 100644 --- a/app/display/gimpdisplayshell-draw.c +++ b/app/display/gimpdisplayshell-draw.c @@ -720,6 +720,8 @@ gimp_display_shell_new (GimpDisplay *gdisp, shell->canvas = gimp_canvas_new (); + shell->select = gimp_display_shell_selection_new (shell); + /* the horizontal ruler */ shell->hrule = gtk_hruler_new (); gtk_widget_set_events (GTK_WIDGET (shell->hrule), @@ -1245,11 +1247,10 @@ gimp_display_shell_draw_guide (GimpDisplayShell *shell, GimpGuide *guide, gboolean active) { - GimpCanvasStyle style = 0; - gint x1, x2; - gint y1, y2; - gint x, y; - gint w, h; + gint x1, x2; + gint y1, y2; + gint x, y; + gint w, h; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (guide != NULL); @@ -1276,27 +1277,22 @@ gimp_display_shell_draw_guide (GimpDisplayShell *shell, gimp_display_shell_transform_xy (shell, 0, guide->position, &x, &y, FALSE); y1 = y2 = y; - - style = (active ? - GIMP_CANVAS_STYLE_HGUIDE_ACTIVE : - GIMP_CANVAS_STYLE_HGUIDE_NORMAL); break; case GIMP_ORIENTATION_VERTICAL: gimp_display_shell_transform_xy (shell, guide->position, 0, &x, &y, FALSE); x1 = x2 = x; - - style = (active ? - GIMP_CANVAS_STYLE_VGUIDE_ACTIVE : - GIMP_CANVAS_STYLE_VGUIDE_NORMAL); break; case GIMP_ORIENTATION_UNKNOWN: return; } - gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), style, x1, y1, x2, y2); + gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), + (active ? + GIMP_CANVAS_STYLE_GUIDE_ACTIVE : + GIMP_CANVAS_STYLE_GUIDE_NORMAL), x1, y1, x2, y2); } void diff --git a/app/display/gimpdisplayshell-marching-ants.h b/app/display/gimpdisplayshell-marching-ants.h deleted file mode 100644 index 28c5802fc3..0000000000 --- a/app/display/gimpdisplayshell-marching-ants.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef __GIMP_DISPLAY_SHELL_MARCHING_ANTS_H__ -#define __GIMP_DISPLAY_SHELL_MARCHING_ANTS_H__ - - -static guchar ant_data[8][8] = -{ - { - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - 0x87, /* #----### */ - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - }, - { - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - 0x87, /* #----### */ - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - 0xF0, /* ####---- */ - }, - { - 0xC3, /* ##----## */ - 0x87, /* #----### */ - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - }, - { - 0x87, /* #----### */ - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - }, - { - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - 0x87, /* #----### */ - }, - { - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - 0x87, /* #----### */ - 0x0F, /* ----#### */ - }, - { - 0x3C, /* --####-- */ - 0x78, /* -####--- */ - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - 0x87, /* #----### */ - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - }, - { - 0x78, /* -####--- */ - 0xF0, /* ####---- */ - 0xE1, /* ###----# */ - 0xC3, /* ##----## */ - 0x87, /* #----### */ - 0x0F, /* ----#### */ - 0x1E, /* ---####- */ - 0x3C, /* --####-- */ - }, -}; - - -#endif /* __GIMP_DISPLAY_SHELL_MARCHING_ANTS_H__ */ diff --git a/app/display/gimpdisplayshell-selection.c b/app/display/gimpdisplayshell-selection.c index 63c4de7168..189823b360 100644 --- a/app/display/gimpdisplayshell-selection.c +++ b/app/display/gimpdisplayshell-selection.c @@ -30,15 +30,16 @@ #include "core/gimpchannel.h" #include "core/gimpimage.h" +#include "gimpcanvas.h" #include "gimpdisplay.h" #include "gimpdisplayshell.h" #include "gimpdisplayshell-appearance.h" -#include "gimpdisplayshell-marching-ants.h" #include "gimpdisplayshell-selection.h" #include "gimpdisplayshell-transform.h" -#undef VERBOSE +#define USE_DRAWPOINTS +#undef VERBOSE /* The possible internal drawing states... */ #define INVISIBLE 0 @@ -66,141 +67,42 @@ static void selection_free_segs (Selection *select); static gboolean selection_start_marching (gpointer data); static gboolean selection_march_ants (gpointer data); -static GdkPixmap *marching_ants[9] = { NULL }; - /* public functions */ Selection * -gimp_display_shell_selection_create (GdkWindow *win, - GimpDisplayShell *shell, - gint size, - gint width) +gimp_display_shell_selection_new (GimpDisplayShell *shell) { - GimpImage *gimage; - GdkColor fg, bg; Selection *new; - gint base_type; gint i; g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL); new = g_new0 (Selection, 1); - gimage = shell->gdisp->gimage; - base_type = gimp_image_base_type (gimage); - - if (! marching_ants[0]) - for (i = 0; i < 8; i++) - marching_ants[i] = gdk_bitmap_create_from_data (win, - (gchar *) ant_data[i], - 8, 8); - - new->win = win; - new->shell = shell; - new->segs_in = NULL; - new->segs_out = NULL; - new->segs_layer = NULL; - new->num_segs_in = 0; - new->num_segs_out = 0; - new->num_segs_layer = 0; - new->index_in = 0; - new->state = INVISIBLE; - new->paused = 0; - new->recalc = TRUE; - new->hidden = ! gimp_display_shell_get_show_selection (shell); - new->layer_hidden = ! gimp_display_shell_get_show_layer (shell); + new->shell = shell; + new->state = INVISIBLE; + new->recalc = TRUE; + new->hidden = ! gimp_display_shell_get_show_selection (shell); + new->layer_hidden = ! gimp_display_shell_get_show_layer (shell); for (i = 0; i < 8; i++) new->points_in[i] = NULL; - /* create a new graphics context */ - new->gc_in = gdk_gc_new (new->win); - - /* get black and white pixels for this gdisplay */ - fg.red = 0x0; - fg.green = 0x0; - fg.blue = 0x0; - - bg.red = 0xffff; - bg.green = 0xffff; - bg.blue = 0xffff; - - gdk_gc_set_rgb_fg_color (new->gc_in, &fg); - gdk_gc_set_rgb_bg_color (new->gc_in, &bg); - gdk_gc_set_fill (new->gc_in, GDK_OPAQUE_STIPPLED); - gdk_gc_set_line_attributes (new->gc_in, - 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); - - new->gc_white = gdk_gc_new (new->win); - gdk_gc_set_rgb_fg_color (new->gc_white, &bg); - - new->gc_black = gdk_gc_new (new->win); - gdk_gc_set_rgb_fg_color (new->gc_black, &fg); - - /* Setup 2nd & 3rd GCs */ - fg.red = 0xffff; - fg.green = 0xffff; - fg.blue = 0xffff; - - bg.red = 0x7f7f; - bg.green = 0x7f7f; - bg.blue = 0x7f7f; - - /* create a new graphics context */ - new->gc_out = gdk_gc_new (new->win); - gdk_gc_set_rgb_fg_color (new->gc_out, &fg); - gdk_gc_set_rgb_bg_color (new->gc_out, &bg); - gdk_gc_set_fill (new->gc_out, GDK_OPAQUE_STIPPLED); - gdk_gc_set_stipple (new->gc_out, marching_ants[0]); - gdk_gc_set_line_attributes (new->gc_out, 1, - GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); - - /* get black and color pixels for this gdisplay */ - fg.red = 0x0; - fg.green = 0x0; - fg.blue = 0x0; - - bg.red = 0xffff; - bg.green = 0xffff; - bg.blue = 0x0; - - /* create a new graphics context */ - new->gc_layer = gdk_gc_new (new->win); - gdk_gc_set_rgb_fg_color (new->gc_layer, &fg); - gdk_gc_set_rgb_bg_color (new->gc_layer, &bg); - gdk_gc_set_fill (new->gc_layer, GDK_OPAQUE_STIPPLED); - gdk_gc_set_stipple (new->gc_layer, marching_ants[0]); - gdk_gc_set_line_attributes (new->gc_layer, 1, - GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); - return new; } - void gimp_display_shell_selection_free (Selection *select) { if (select->timeout_id) g_source_remove (select->timeout_id); - if (select->gc_in) - g_object_unref (select->gc_in); - if (select->gc_out) - g_object_unref (select->gc_out); - if (select->gc_layer) - g_object_unref (select->gc_layer); - if (select->gc_white) - g_object_unref (select->gc_white); - if (select->gc_black) - g_object_unref (select->gc_black); - selection_free_segs (select); g_free (select); } - void gimp_display_shell_selection_pause (Selection *select) { @@ -215,7 +117,6 @@ gimp_display_shell_selection_pause (Selection *select) select->paused++; } - void gimp_display_shell_selection_resume (Selection *select) { @@ -230,7 +131,6 @@ gimp_display_shell_selection_resume (Selection *select) select->paused--; } - void gimp_display_shell_selection_start (Selection *select, gboolean recalc) @@ -258,7 +158,6 @@ gimp_display_shell_selection_start (Selection *select, select); } - void gimp_display_shell_selection_invis (Selection *select) { @@ -276,8 +175,7 @@ gimp_display_shell_selection_invis (Selection *select) if (gimp_display_shell_mask_bounds (select->shell, &x1, &y1, &x2, &y2)) { gimp_display_shell_expose_area (select->shell, - x1, y1, - (x2 - x1), (y2 - y1)); + x1, y1, (x2 - x1), (y2 - y1)); } else { @@ -383,6 +281,7 @@ selection_add_point (GdkPoint *points[8], max_npoints[j] += 2048; points[j] = g_realloc (points[j], sizeof (GdkPoint) * max_npoints[j]); } + points[j][i].x = x; points[j][i].y = y; } @@ -473,10 +372,12 @@ selection_render_points (Selection *select) } while (y != select->segs_in[i].y2); } else - selection_add_point (select->points_in, - max_npoints, - select->num_points_in, - x, y); + { + selection_add_point (select->points_in, + max_npoints, + select->num_points_in, + x, y); + } } } @@ -484,12 +385,20 @@ selection_render_points (Selection *select) static void selection_draw (Selection *select) { + GimpCanvas *canvas = GIMP_CANVAS (select->shell->canvas); + if (select->hidden) return; + if (! GTK_WIDGET_REALIZED (canvas)) + return; + +#ifdef USE_DRAWPOINTS + #ifdef VERBOSE { gint j, sum; + sum = 0; for (j = 0; j < 8; j++) sum += select->num_points_in[j]; @@ -501,29 +410,42 @@ selection_draw (Selection *select) { gint i; - if (select->index_in == 0) + if (select->index == 0) { for (i = 0; i < 4; i++) if (select->num_points_in[i]) - gdk_draw_points (select->win, select->gc_white, - select->points_in[i], select->num_points_in[i]); + gimp_canvas_draw_points (canvas, GIMP_CANVAS_STYLE_WHITE, + select->points_in[i], + select->num_points_in[i]); for (i = 4; i < 8; i++) if (select->num_points_in[i]) - gdk_draw_points (select->win, select->gc_black, - select->points_in[i], select->num_points_in[i]); + gimp_canvas_draw_points (canvas, GIMP_CANVAS_STYLE_BLACK, + select->points_in[i], + select->num_points_in[i]); } else { - i = ((select->index_in + 3) & 7); + i = ((select->index + 3) & 7); if (select->num_points_in[i]) - gdk_draw_points (select->win, select->gc_white, - select->points_in[i], select->num_points_in[i]); - i = ((select->index_in + 7) & 7); + gimp_canvas_draw_points (canvas, GIMP_CANVAS_STYLE_WHITE, + select->points_in[i], + select->num_points_in[i]); + i = ((select->index + 7) & 7); if (select->num_points_in[i]) - gdk_draw_points (select->win, select->gc_black, - select->points_in[i], select->num_points_in[i]); + gimp_canvas_draw_points (canvas, GIMP_CANVAS_STYLE_BLACK, + select->points_in[i], + select->num_points_in[i]); } } + +#else /* ! USE_DRAWPOINTS */ + gimp_canvas_set_stipple_index (canvas, + GIMP_CANVAS_STYLE_SELECTION_IN, + select->index); + if (select->segs_in) + gimp_canvas_draw_segments (canvas, GIMP_CANVAS_STYLE_SELECTION_IN, + select->segs_in, select->num_segs_in); +#endif } @@ -602,7 +524,9 @@ selection_generate_segs (Selection *select) selection_transform_segs (select, segs_in, select->segs_in, select->num_segs_in); +#ifdef USE_DRAWPOINTS selection_render_points (select); +#endif } else { @@ -674,11 +598,11 @@ selection_free_segs (Selection *select) static gboolean selection_start_marching (gpointer data) { - Selection *select; + Selection *select = (Selection *) data; + GimpCanvas *canvas; GimpDisplayConfig *config; - select = (Selection *) data; - + canvas = GIMP_CANVAS (select->shell->canvas); config = GIMP_DISPLAY_CONFIG (select->shell->gdisp->gimage->gimp->config); /* if the RECALC bit is set, reprocess the boundaries */ @@ -691,23 +615,21 @@ selection_start_marching (gpointer data) select->recalc = FALSE; } - select->index_in = 0; + select->index = 0; /* Make sure the state is set to marching */ select->state = MARCHING; - /* Draw the ants */ - gdk_gc_set_stipple (select->gc_in, marching_ants[0]); - if (! select->layer_hidden && select->segs_layer) - gdk_draw_segments (select->win, select->gc_layer, - select->segs_layer, select->num_segs_layer); + gimp_canvas_draw_segments (canvas, GIMP_CANVAS_STYLE_LAYER_BOUNDARY, + select->segs_layer, select->num_segs_layer); + /* Draw the ants */ selection_draw (select); if (select->segs_out) - gdk_draw_segments (select->win, select->gc_out, - select->segs_out, select->num_segs_out); + gimp_canvas_draw_segments (canvas, GIMP_CANVAS_STYLE_SELECTION_OUT, + select->segs_out, select->num_segs_out); /* Reset the timer */ select->timeout_id = g_timeout_add (config->marching_ants_speed, @@ -723,15 +645,7 @@ selection_march_ants (gpointer data) { Selection *select = (Selection *) data; - /* increment stipple index */ - select->index_in++; - - if (select->index_in > 7) - select->index_in = 0; - - /* Draw the ants */ - gdk_gc_set_stipple (select->gc_in, marching_ants[select->index_in]); - + select->index++; selection_draw (select); return TRUE; diff --git a/app/display/gimpdisplayshell-selection.h b/app/display/gimpdisplayshell-selection.h index de20d5ad44..d9fe957084 100644 --- a/app/display/gimpdisplayshell-selection.h +++ b/app/display/gimpdisplayshell-selection.h @@ -22,22 +22,15 @@ struct _Selection { - /* This information is for maintaining the selection's appearance */ - GdkWindow *win; /* Window to draw to */ - GimpDisplayShell *shell; /* GimpDisplay that owns the selection */ - GdkGC *gc_in; /* GC for drawing selection outline */ - GdkGC *gc_out; /* GC for selected regions outside * - * current layer */ - GdkGC *gc_layer; /* GC for current layer outline */ + GimpDisplayShell *shell; /* shell that owns the selection */ - /* This information is for drawing the marching ants around the border */ GdkSegment *segs_in; /* gdk segments of area boundary */ GdkSegment *segs_out; /* gdk segments of area boundary */ GdkSegment *segs_layer; /* gdk segments of area boundary */ gint num_segs_in; /* number of segments in segs1 */ gint num_segs_out; /* number of segments in segs2 */ gint num_segs_layer; /* number of segments in segs3 */ - gint index_in; /* index of current stipple pattern */ + guint index; /* index of current stipple pattern */ gint state; /* internal drawing state */ gint paused; /* count of pause requests */ gboolean recalc; /* flag to recalculate the selection */ @@ -45,19 +38,12 @@ struct _Selection gboolean layer_hidden; /* is the layer boundary hidden? */ guint timeout_id; /* timer for successive draws */ GdkPixmap *cycle_pix; /* cycling pixmap */ - - /* These are used only if USE_XDRAWPOINTS is defined. */ GdkPoint *points_in[8]; /* points of segs_in for fast ants */ gint num_points_in[8]; /* number of points in points_in */ - GdkGC *gc_white; /* gc for drawing white points */ - GdkGC *gc_black; /* gc for drawing black points */ }; -Selection * gimp_display_shell_selection_create (GdkWindow *window, - GimpDisplayShell *gdisp, - gint size, - gint width); +Selection * gimp_display_shell_selection_new (GimpDisplayShell *shell); void gimp_display_shell_selection_free (Selection *select); void gimp_display_shell_selection_pause (Selection *select); diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index b50c4ef2b3..ceaf1a2931 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -720,6 +720,8 @@ gimp_display_shell_new (GimpDisplay *gdisp, shell->canvas = gimp_canvas_new (); + shell->select = gimp_display_shell_selection_new (shell); + /* the horizontal ruler */ shell->hrule = gtk_hruler_new (); gtk_widget_set_events (GTK_WIDGET (shell->hrule), @@ -1245,11 +1247,10 @@ gimp_display_shell_draw_guide (GimpDisplayShell *shell, GimpGuide *guide, gboolean active) { - GimpCanvasStyle style = 0; - gint x1, x2; - gint y1, y2; - gint x, y; - gint w, h; + gint x1, x2; + gint y1, y2; + gint x, y; + gint w, h; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (guide != NULL); @@ -1276,27 +1277,22 @@ gimp_display_shell_draw_guide (GimpDisplayShell *shell, gimp_display_shell_transform_xy (shell, 0, guide->position, &x, &y, FALSE); y1 = y2 = y; - - style = (active ? - GIMP_CANVAS_STYLE_HGUIDE_ACTIVE : - GIMP_CANVAS_STYLE_HGUIDE_NORMAL); break; case GIMP_ORIENTATION_VERTICAL: gimp_display_shell_transform_xy (shell, guide->position, 0, &x, &y, FALSE); x1 = x2 = x; - - style = (active ? - GIMP_CANVAS_STYLE_VGUIDE_ACTIVE : - GIMP_CANVAS_STYLE_VGUIDE_NORMAL); break; case GIMP_ORIENTATION_UNKNOWN: return; } - gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), style, x1, y1, x2, y2); + gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), + (active ? + GIMP_CANVAS_STYLE_GUIDE_ACTIVE : + GIMP_CANVAS_STYLE_GUIDE_NORMAL), x1, y1, x2, y2); } void