[gimp] app: port GimpDisplayShell grid drawing to cairo
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: port GimpDisplayShell grid drawing to cairo
- Date: Wed, 11 Aug 2010 11:17:32 +0000 (UTC)
commit 529ce40a5d92d9c9957c7e8350ce48ffbcad033a
Author: Michael Natterer <mitch gimp org>
Date: Wed Aug 11 13:16:55 2010 +0200
app: port GimpDisplayShell grid drawing to cairo
app/display/gimpdisplayshell-callbacks.c | 12 ++-
app/display/gimpdisplayshell-draw.c | 185 ++++++++++++++++++------------
app/display/gimpdisplayshell-draw.h | 2 +-
app/display/gimpdisplayshell-handlers.c | 12 --
app/display/gimpdisplayshell.c | 6 -
app/display/gimpdisplayshell.h | 1 -
6 files changed, 121 insertions(+), 97 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c
index 52159c0..f4d592e 100644
--- a/app/display/gimpdisplayshell-callbacks.c
+++ b/app/display/gimpdisplayshell-callbacks.c
@@ -2216,6 +2216,7 @@ static void
gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
GdkEventExpose *eevent)
{
+ cairo_t *cr;
GdkRegion *clear_region;
GdkRegion *image_region;
GdkRectangle image_rect;
@@ -2223,6 +2224,11 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
gint n_rects;
gint i;
+ cr = gdk_cairo_create (eevent->window);
+
+ gdk_cairo_region (cr, eevent->region);
+ cairo_clip (cr);
+
/* first, clear the exposed part of the region that is outside the
* image, which is the exposed region minus the image rectangle
*/
@@ -2286,7 +2292,9 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
gimp_display_shell_preview_transform (shell);
/* draw the grid */
- gimp_display_shell_draw_grid (shell, eevent->region);
+ cairo_save (cr);
+ gimp_display_shell_draw_grid (shell, cr);
+ cairo_restore (cr);
/* draw the guides */
gimp_display_shell_draw_guides (shell, eevent->region);
@@ -2299,6 +2307,8 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
/* restart (and recalculate) the selection boundaries */
gimp_display_shell_selection_control (shell, GIMP_SELECTION_ON);
+
+ cairo_destroy (cr);
}
static void
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 4889a1b..0a72ca3 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -21,6 +21,7 @@
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
@@ -56,11 +57,12 @@
/* local function prototypes */
-static GdkGC * gimp_display_shell_get_grid_gc (GimpDisplayShell *shell,
- GimpGrid *grid);
-static GdkGC * gimp_display_shell_get_pen_gc (GimpDisplayShell *shell,
- GimpContext *context,
- GimpActiveColor active);
+static void gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
+ GimpGrid *grid,
+ cairo_t *cr);
+static GdkGC * gimp_display_shell_get_pen_gc (GimpDisplayShell *shell,
+ GimpContext *context,
+ GimpActiveColor active);
/* public functions */
@@ -226,27 +228,25 @@ gimp_display_shell_draw_guides (GimpDisplayShell *shell,
void
gimp_display_shell_draw_grid (GimpDisplayShell *shell,
- const GdkRegion *region)
+ cairo_t *cr)
{
GimpImage *image;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
- g_return_if_fail (region != NULL);
+ g_return_if_fail (cr != NULL);
image = gimp_display_get_image (shell->display);
if (image && gimp_display_shell_get_show_grid (shell))
{
- GimpCanvas *canvas = GIMP_CANVAS (shell->canvas);
- GimpGrid *grid;
- GdkRectangle area;
- GdkGC *grid_gc;
- gdouble x, y;
- gint x0, x1, x2, x3;
- gint y0, y1, y2, y3;
- gint x_real, y_real;
- gdouble x_offset, y_offset;
- gint width, height;
+ GimpGrid *grid;
+ gdouble x, y;
+ gdouble dx1, dy1, dx2, dy2;
+ gint x0, x1, x2, x3;
+ gint y0, y1, y2, y3;
+ gint x_real, y_real;
+ gdouble x_offset, y_offset;
+ gint width, height;
#define CROSSHAIR 2
@@ -256,12 +256,12 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
g_return_if_fail (grid->xspacing > 0 && grid->yspacing > 0);
- gdk_region_get_clipbox (region, &area);
+ cairo_clip_extents (cr, &dx1, &dy1, &dx2, &dy2);
- x1 = area.x;
- y1 = area.y;
- x2 = area.x + area.width;
- y2 = area.y + area.height;
+ x1 = floor (dx1);
+ y1 = floor (dy1);
+ x2 = ceil (dx2);
+ y2 = ceil (dy2);
width = gimp_image_get_width (image);
height = gimp_image_get_height (image);
@@ -274,10 +274,7 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
while (y_offset > 0)
y_offset -= grid->yspacing;
- grid_gc = gimp_display_shell_get_grid_gc (shell, grid);
-
- gdk_gc_set_clip_region (grid_gc, region);
- gimp_canvas_set_custom_gc (canvas, grid_gc);
+ gimp_display_shell_set_grid_style (shell, grid, cr);
switch (grid->style)
{
@@ -304,9 +301,10 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
FALSE);
if (y_real >= y1 && y_real < y2)
- gimp_canvas_draw_point (GIMP_CANVAS (shell->canvas),
- GIMP_CANVAS_STYLE_CUSTOM,
- x_real, y_real);
+ {
+ cairo_move_to (cr, x_real, y_real + 0.5);
+ cairo_line_to (cr, x_real + 1, y_real + 0.5);
+ }
}
}
break;
@@ -337,21 +335,28 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
continue;
if (x_real >= x1 && x_real < x2)
- gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
- x_real,
- CLAMP (y_real - CROSSHAIR,
- y1, y2 - 1),
- x_real,
- CLAMP (y_real + CROSSHAIR,
- y1, y2 - 1));
+ {
+ cairo_move_to (cr,
+ x_real + 0.5,
+ CLAMP (y_real - CROSSHAIR,
+ y1, y2 - 1));
+ cairo_line_to (cr,
+ x_real + 0.5,
+ CLAMP (y_real + CROSSHAIR,
+ y1, y2 - 1) + 1);
+ }
+
if (y_real >= y1 && y_real < y2)
- gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
- CLAMP (x_real - CROSSHAIR,
- x1, x2 - 1),
- y_real,
- CLAMP (x_real + CROSSHAIR,
- x1, x2 - 1),
- y_real);
+ {
+ cairo_move_to (cr,
+ CLAMP (x_real - CROSSHAIR,
+ x1, x2 - 1),
+ y_real + 0.5);
+ cairo_line_to (cr,
+ CLAMP (x_real + CROSSHAIR,
+ x1, x2 - 1) + 1,
+ y_real + 0.5);
+ }
}
}
break;
@@ -376,8 +381,10 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
FALSE);
if (x_real >= x1 && x_real < x2)
- gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
- x_real, y0, x_real, y3 - 1);
+ {
+ cairo_move_to (cr, x_real + 0.5, y0);
+ cairo_line_to (cr, x_real + 0.5, y3 + 1);
+ }
}
for (y = y_offset; y < height; y += grid->yspacing)
@@ -390,14 +397,15 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
FALSE);
if (y_real >= y1 && y_real < y2)
- gimp_canvas_draw_line (canvas, GIMP_CANVAS_STYLE_CUSTOM,
- x0, y_real, x3 - 1, y_real);
+ {
+ cairo_move_to (cr, x0, y_real + 0.5);
+ cairo_line_to (cr, x3 + 1, y_real + 0.5);
+ }
}
break;
}
- gimp_canvas_set_custom_gc (canvas, NULL);
- gdk_gc_set_clip_region (grid_gc, NULL);
+ cairo_stroke (cr);
}
}
@@ -692,46 +700,71 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
/* private functions */
-static GdkGC *
-gimp_display_shell_get_grid_gc (GimpDisplayShell *shell,
- GimpGrid *grid)
+static void
+gimp_display_shell_set_grid_style (GimpDisplayShell *shell,
+ GimpGrid *grid,
+ cairo_t *cr)
{
- GdkGCValues values;
- GdkColor fg, bg;
-
- if (shell->grid_gc)
- return shell->grid_gc;
+ cairo_set_line_width (cr, 1.0);
switch (grid->style)
{
case GIMP_GRID_ON_OFF_DASH:
- values.line_style = GDK_LINE_ON_OFF_DASH;
- break;
-
case GIMP_GRID_DOUBLE_DASH:
- values.line_style = GDK_LINE_DOUBLE_DASH;
+ {
+ guchar *data = g_malloc0 (8 * 8 * 4);
+ guchar fg_r, fg_g, fg_b, fg_a;
+ guchar bg_r, bg_g, bg_b, bg_a;
+ gint x, y;
+ guchar *d;
+ cairo_surface_t *surface;
+ static cairo_user_data_key_t data_key;
+
+ gimp_rgba_get_uchar (&grid->fgcolor, &fg_r, &fg_g, &fg_b, &fg_a);
+
+ if (grid->style == GIMP_GRID_DOUBLE_DASH)
+ gimp_rgba_get_uchar (&grid->bgcolor, &bg_r, &bg_g, &bg_b, &bg_a);
+ else
+ bg_r = bg_g = bg_b = bg_a = 0;
+
+ d = data;
+
+ for (y = 0; y < 8; y++)
+ {
+ for (x = 0; x < 8; x++)
+ {
+ if ((y < 4 && x < 4) || (y >= 4 && x >= 4))
+ GIMP_CAIRO_ARGB32_SET_PIXEL (d, fg_r, fg_g, fg_b, fg_a);
+ else
+ GIMP_CAIRO_ARGB32_SET_PIXEL (d, bg_r, bg_g, bg_b, bg_a);
+
+ d += 4;
+ }
+ }
+
+ surface = cairo_image_surface_create_for_data (data,
+ CAIRO_FORMAT_ARGB32,
+ 8, 8, 8 * 4);
+ cairo_surface_set_user_data (surface, &data_key,
+ data, (cairo_destroy_func_t) g_free);
+
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_surface_destroy (surface);
+
+ cairo_pattern_set_extend (cairo_get_source (cr),
+ CAIRO_EXTEND_REPEAT);
+ }
break;
case GIMP_GRID_DOTS:
case GIMP_GRID_INTERSECTIONS:
case GIMP_GRID_SOLID:
- values.line_style = GDK_LINE_SOLID;
+ cairo_set_source_rgb (cr,
+ grid->fgcolor.r,
+ grid->fgcolor.g,
+ grid->fgcolor.b);
break;
}
-
- values.join_style = GDK_JOIN_MITER;
-
- shell->grid_gc = gdk_gc_new_with_values (gtk_widget_get_window (shell->canvas),
- &values, (GDK_GC_LINE_STYLE |
- GDK_GC_JOIN_STYLE));
-
- gimp_rgb_get_gdk_color (&grid->fgcolor, &fg);
- gdk_gc_set_rgb_fg_color (shell->grid_gc, &fg);
-
- gimp_rgb_get_gdk_color (&grid->bgcolor, &bg);
- gdk_gc_set_rgb_bg_color (shell->grid_gc, &bg);
-
- return shell->grid_gc;
}
static GdkGC *
diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h
index b756f62..1f48106 100644
--- a/app/display/gimpdisplayshell-draw.h
+++ b/app/display/gimpdisplayshell-draw.h
@@ -34,7 +34,7 @@ void gimp_display_shell_draw_guide (GimpDisplayShell *shell,
void gimp_display_shell_draw_guides (GimpDisplayShell *shell,
const GdkRegion *region);
void gimp_display_shell_draw_grid (GimpDisplayShell *shell,
- const GdkRegion *region);
+ cairo_t *cr);
void gimp_display_shell_draw_pen (GimpDisplayShell *shell,
const GimpVector2 *points,
gint num_points,
diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c
index 69b68e2..f494e85 100644
--- a/app/display/gimpdisplayshell-handlers.c
+++ b/app/display/gimpdisplayshell-handlers.c
@@ -304,12 +304,6 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
gimp_display_shell_icon_update_stop (shell);
- if (shell->grid_gc)
- {
- g_object_unref (shell->grid_gc);
- shell->grid_gc = NULL;
- }
-
if (shell->pen_gc)
{
g_object_unref (shell->pen_gc);
@@ -426,12 +420,6 @@ gimp_display_shell_grid_notify_handler (GimpGrid *grid,
GParamSpec *pspec,
GimpDisplayShell *shell)
{
- if (shell->grid_gc)
- {
- g_object_unref (shell->grid_gc);
- shell->grid_gc = NULL;
- }
-
gimp_display_shell_expose_full (shell);
/* update item factory */
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index 4bfae00..2860db3 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -938,12 +938,6 @@ gimp_display_shell_unrealize (GtkWidget *widget)
{
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (widget);
- if (shell->grid_gc)
- {
- g_object_unref (shell->grid_gc);
- shell->grid_gc = NULL;
- }
-
if (shell->pen_gc)
{
g_object_unref (shell->pen_gc);
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index 562eb4e..d4ebfc9 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -115,7 +115,6 @@ struct _GimpDisplayShell
GList *children;
GtkWidget *canvas; /* GimpCanvas widget */
- GdkGC *grid_gc; /* GC for grid drawing */
GdkGC *pen_gc; /* GC for felt pen drawing */
GtkAdjustment *hsbdata; /* adjustments */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]