[gimp] app: port GimpDisplayShell image drawing to cairo
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: port GimpDisplayShell image drawing to cairo
- Date: Fri, 27 Aug 2010 21:25:19 +0000 (UTC)
commit f0c40d3717c9778bb40fa2bb9c1eef3ab15c6862
Author: Michael Natterer <mitch gimp org>
Date: Fri Aug 27 19:32:16 2010 +0200
app: port GimpDisplayShell image drawing to cairo
app/display/gimpcanvas.c | 42 -------------
app/display/gimpcanvas.h | 11 ----
app/display/gimpdisplayshell-callbacks.c | 6 ++-
app/display/gimpdisplayshell-draw.c | 4 +-
app/display/gimpdisplayshell-draw.h | 1 +
app/display/gimpdisplayshell-render.c | 93 +++++++++++++++++-------------
app/display/gimpdisplayshell-render.h | 1 +
app/display/gimpdisplayshell.c | 12 ++--
app/display/gimpdisplayshell.h | 2 +-
9 files changed, 69 insertions(+), 103 deletions(-)
---
diff --git a/app/display/gimpcanvas.c b/app/display/gimpcanvas.c
index 2004227..f068de9 100644
--- a/app/display/gimpcanvas.c
+++ b/app/display/gimpcanvas.c
@@ -258,11 +258,6 @@ gimp_canvas_gc_new (GimpCanvas *canvas,
switch (style)
{
- case GIMP_CANVAS_STYLE_RENDER:
- mask |= GDK_GC_EXPOSURES;
- values.graphics_exposures = TRUE;
- break;
-
case GIMP_CANVAS_STYLE_XOR_DOTTED:
case GIMP_CANVAS_STYLE_XOR_DASHED:
mask |= GDK_GC_LINE_STYLE;
@@ -556,43 +551,6 @@ gimp_canvas_get_layout (GimpCanvas *canvas,
return canvas->layout;
}
-/**
- * gimp_canvas_draw_rgb:
- * @canvas: a #GimpCanvas widget
- * @style: one of the enumerated #GimpCanvasStyle's.
- * @x: X coordinate of the upper left corner.
- * @y: Y coordinate of the upper left corner.
- * @width: width of the rectangle to be drawn.
- * @height: height of the rectangle to be drawn.
- * @rgb_buf: pixel data for the image to be drawn.
- * @rowstride: the rowstride in @rgb_buf.
- * @xdith: x offset for dither alignment.
- * @ydith: y offset for dither alignment.
- *
- * Draws an RGB image on the canvas in the specified style.
- **/
-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)
-{
- if (! gimp_canvas_ensure_style (canvas, style))
- return;
-
- gdk_draw_rgb_image_dithalign (gtk_widget_get_window (GTK_WIDGET (canvas)),
- canvas->gc[style],
- x, y, width, height,
- GDK_RGB_DITHER_MAX,
- rgb_buf, rowstride, xdith, ydith);
-}
-
void
gimp_canvas_draw_drop_zone (GimpCanvas *canvas,
cairo_t *cr)
diff --git a/app/display/gimpcanvas.h b/app/display/gimpcanvas.h
index 7c7ef45..6373ff9 100644
--- a/app/display/gimpcanvas.h
+++ b/app/display/gimpcanvas.h
@@ -24,7 +24,6 @@
typedef enum
{
- GIMP_CANVAS_STYLE_RENDER,
GIMP_CANVAS_STYLE_XOR,
GIMP_CANVAS_STYLE_XOR_DASHED,
GIMP_CANVAS_STYLE_XOR_DOTTED,
@@ -116,16 +115,6 @@ void gimp_canvas_draw_segments (GimpCanvas *canvas,
PangoLayout *gimp_canvas_get_layout (GimpCanvas *canvas,
const gchar *format,
...) G_GNUC_PRINTF (2, 3);
-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_drop_zone (GimpCanvas *canvas,
cairo_t *cr);
diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c
index 49e5e75..d8df28b 100644
--- a/app/display/gimpdisplayshell-callbacks.c
+++ b/app/display/gimpdisplayshell-callbacks.c
@@ -2273,13 +2273,17 @@ gimp_display_shell_canvas_expose_image (GimpDisplayShell *shell,
{
gdk_region_get_rectangles (image_region, &rects, &n_rects);
+ cairo_save (cr);
+
for (i = 0; i < n_rects; i++)
- gimp_display_shell_draw_area (shell,
+ gimp_display_shell_draw_area (shell, cr,
rects[i].x,
rects[i].y,
rects[i].width,
rects[i].height);
+ cairo_restore (cr);
+
g_free (rects);
}
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 28bfc00..d900412 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -692,6 +692,7 @@ gimp_display_shell_draw_cursor (GimpDisplayShell *shell,
void
gimp_display_shell_draw_area (GimpDisplayShell *shell,
+ cairo_t *cr,
gint x,
gint y,
gint w,
@@ -703,6 +704,7 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (gimp_display_get_image (shell->display));
+ g_return_if_fail (cr != NULL);
x2 = x + w;
y2 = y + h;
@@ -732,7 +734,7 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell,
&disp_xoffset,
&disp_yoffset);
- gimp_display_shell_render (shell,
+ gimp_display_shell_render (shell, cr,
j - disp_xoffset,
i - disp_yoffset,
dx, dy,
diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h
index 9ad1e62..5f51ba2 100644
--- a/app/display/gimpdisplayshell-draw.h
+++ b/app/display/gimpdisplayshell-draw.h
@@ -67,6 +67,7 @@ void gimp_display_shell_draw_vectors (GimpDisplayShell *shell)
void gimp_display_shell_draw_cursor (GimpDisplayShell *shell,
cairo_t *cr);
void gimp_display_shell_draw_area (GimpDisplayShell *shell,
+ cairo_t *cr,
gint x,
gint y,
gint w,
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index 956c424..b229ed0 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -76,7 +76,6 @@ struct _RenderInfo
gint src_y;
gint dest_bpp;
gint dest_bpl;
- gint dest_width;
gint zoom_quality;
@@ -195,6 +194,7 @@ static const guchar * render_image_tile_fault (RenderInfo *info);
static void gimp_display_shell_render_highlight (GimpDisplayShell *shell,
+ RenderInfo *info,
gint x,
gint y,
gint w,
@@ -213,6 +213,7 @@ static void gimp_display_shell_render_mask (GimpDisplayShell *shell,
void
gimp_display_shell_render (GimpDisplayShell *shell,
+ cairo_t *cr,
gint x,
gint y,
gint w,
@@ -227,6 +228,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gint offset_y;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+ g_return_if_fail (cr != NULL);
g_return_if_fail (w > 0 && h > 0);
image = gimp_display_get_image (shell->display);
@@ -239,16 +241,15 @@ gimp_display_shell_render (GimpDisplayShell *shell,
/* Initialize RenderInfo with values that don't change during the
* call of this function.
*/
- info.shell = shell;
+ info.shell = shell;
- info.x = x + offset_x;
- info.y = y + offset_y;
- info.w = w;
- info.h = h;
+ info.x = x + offset_x;
+ info.y = y + offset_y;
+ info.w = w;
+ info.h = h;
- info.dest_bpp = 3;
- info.dest_bpl = info.dest_bpp * GIMP_DISPLAY_RENDER_BUF_WIDTH;
- info.dest_width = info.dest_bpp * info.w;
+ info.dest_bpp = 4;
+ info.dest_bpl = cairo_image_surface_get_stride (shell->render_surface);
switch (shell->display->config->zoom_quality)
{
@@ -293,17 +294,19 @@ gimp_display_shell_render (GimpDisplayShell *shell,
}
/* apply filters to the rendered projection */
+#if 0
if (shell->filter_stack)
gimp_color_display_stack_convert (shell->filter_stack,
shell->render_buf,
w, h,
3,
3 * GIMP_DISPLAY_RENDER_BUF_WIDTH);
+#endif
/* dim pixels outside the highlighted rectangle */
if (highlight)
{
- gimp_display_shell_render_highlight (shell, x, y, w, h, highlight);
+ gimp_display_shell_render_highlight (shell, &info, x, y, w, h, highlight);
}
else if (shell->mask)
{
@@ -315,6 +318,8 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gimp_display_shell_render_mask (shell, &info);
}
+ cairo_surface_mark_dirty (shell->render_surface);
+
/* put it to the screen */
{
gint disp_xoffset, disp_yoffset;
@@ -322,35 +327,43 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gimp_display_shell_scroll_get_disp_offset (shell,
&disp_xoffset, &disp_yoffset);
- gimp_canvas_draw_rgb (GIMP_CANVAS (shell->canvas),
- GIMP_CANVAS_STYLE_RENDER,
- x + disp_xoffset, y + disp_yoffset,
- w, h,
- shell->render_buf,
- 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH,
- offset_x, offset_y);
+ cairo_set_source_surface (cr, shell->render_surface,
+ x + disp_xoffset, y + disp_yoffset);
+ cairo_rectangle (cr, x + disp_xoffset, y + disp_yoffset, w, h);
+ cairo_fill (cr);
}
}
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define CAIRO_RGB24_RED_PIXEL 2
+#define CAIRO_RGB24_GREEN_PIXEL 1
+#define CAIRO_RGB24_BLUE_PIXEL 0
+#else
+#define CAIRO_RGB24_RED_PIXEL 1
+#define CAIRO_RGB24_GREEN_PIXEL 2
+#define CAIRO_RGB24_BLUE_PIXEL 3
+#endif
+
#define GIMP_DISPLAY_SHELL_DIM_PIXEL(buf,x) \
{ \
- buf[3 * (x) + 0] >>= 1; \
- buf[3 * (x) + 1] >>= 1; \
- buf[3 * (x) + 2] >>= 1; \
+ buf[4 * (x) + CAIRO_RGB24_RED_PIXEL] >>= 1; \
+ buf[4 * (x) + CAIRO_RGB24_GREEN_PIXEL] >>= 1; \
+ buf[4 * (x) + CAIRO_RGB24_BLUE_PIXEL] >>= 1; \
}
/* This function highlights the given area by dimming all pixels outside. */
static void
gimp_display_shell_render_highlight (GimpDisplayShell *shell,
+ RenderInfo *info,
gint x,
gint y,
gint w,
gint h,
const GdkRectangle *highlight)
{
- guchar *buf = shell->render_buf;
+ guchar *buf = cairo_image_surface_get_data (shell->render_surface);
GdkRectangle rect;
gint offset_x;
gint offset_y;
@@ -373,7 +386,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
for (x = 0; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
- buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
+ buf += info->dest_bpl;
}
for ( ; y < rect.y + rect.height; y++)
@@ -384,7 +397,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
for (x += rect.width; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
- buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
+ buf += info->dest_bpl;
}
for ( ; y < h; y++)
@@ -392,7 +405,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
for (x = 0; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
- buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
+ buf += info->dest_bpl;
}
}
else
@@ -402,7 +415,7 @@ gimp_display_shell_render_highlight (GimpDisplayShell *shell,
for (x = 0; x < w; x++)
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
- buf += 3 * GIMP_DISPLAY_RENDER_BUF_WIDTH;
+ buf += info->dest_bpl;
}
}
}
@@ -429,35 +442,35 @@ gimp_display_shell_render_mask (GimpDisplayShell *shell,
switch (shell->mask_color)
{
case GIMP_RED_CHANNEL:
- for (x = info->x; x < xe; x++, src++, dest += 3)
+ for (x = info->x; x < xe; x++, src++, dest += info->dest_bpp)
{
if (*src & 0x80)
continue;
- dest[1] = dest[1] >> 2;
- dest[2] = dest[2] >> 2;
+ dest[CAIRO_RGB24_GREEN_PIXEL] >>= 2;
+ dest[CAIRO_RGB24_BLUE_PIXEL] >>= 2;
}
break;
case GIMP_GREEN_CHANNEL:
- for (x = info->x; x < xe; x++, src++, dest += 3)
+ for (x = info->x; x < xe; x++, src++, dest += info->dest_bpp)
{
if (*src & 0x80)
continue;
- dest[0] = dest[0] >> 2;
- dest[2] = dest[2] >> 2;
+ dest[CAIRO_RGB24_RED_PIXEL] >>= 2;
+ dest[CAIRO_RGB24_BLUE_PIXEL] >>= 2;
}
break;
case GIMP_BLUE_CHANNEL:
- for (x = info->x; x < xe; x++, src++, dest += 3)
+ for (x = info->x; x < xe; x++, src++, dest += info->dest_bpp)
{
if (*src & 0x80)
continue;
- dest[0] = dest[0] >> 2;
- dest[1] = dest[1] >> 2;
+ dest[CAIRO_RGB24_RED_PIXEL] >>= 2;
+ dest[CAIRO_RGB24_GREEN_PIXEL] >>= 2;
}
break;
@@ -504,7 +517,7 @@ render_image_gray_a (RenderInfo *info)
dark_light = (y >> check_shift) + (info->x >> check_shift);
- for (x = info->x; x < xe; x++, src += 2, dest += 3)
+ for (x = info->x; x < xe; x++, src += 2, dest += info->dest_bpp)
{
guint v;
@@ -513,7 +526,7 @@ render_image_gray_a (RenderInfo *info)
else
v = ((src[0] << 8) + check_light * (256 - src[1])) >> 8;
- dest[0] = dest[1] = dest[2] = v;
+ GIMP_CAIRO_RGB24_SET_PIXEL (dest, v, v, v);
if (((x + 1) & check_mod) == 0)
dark_light += 1;
@@ -553,7 +566,7 @@ render_image_rgb_a (RenderInfo *info)
dark_light = (y >> check_shift) + (info->x >> check_shift);
- for (x = info->x; x < xe; x++, src += 4, dest += 3)
+ for (x = info->x; x < xe; x++, src += 4, dest += info->dest_bpp)
{
guint r, g, b;
@@ -570,9 +583,7 @@ render_image_rgb_a (RenderInfo *info)
b = ((src[2] << 8) + check_light * (256 - src[3])) >> 8;
}
- dest[0] = r;
- dest[1] = g;
- dest[2] = b;
+ GIMP_CAIRO_RGB24_SET_PIXEL (dest, r, g, b);
if (((x + 1) & check_mod) == 0)
dark_light += 1;
@@ -605,7 +616,7 @@ gimp_display_shell_render_info_scale (RenderInfo *info,
/* We must reset info->dest because this member is modified in render
* functions.
*/
- info->dest = shell->render_buf;
+ info->dest = cairo_image_surface_get_data (shell->render_surface);
info->scalex = shell->scale_x * (1 << level);
info->scaley = shell->scale_y * (1 << level);
diff --git a/app/display/gimpdisplayshell-render.h b/app/display/gimpdisplayshell-render.h
index f5e14fa..f60ff65 100644
--- a/app/display/gimpdisplayshell-render.h
+++ b/app/display/gimpdisplayshell-render.h
@@ -27,6 +27,7 @@ void gimp_display_shell_render_init (Gimp *gimp);
void gimp_display_shell_render_exit (Gimp *gimp);
void gimp_display_shell_render (GimpDisplayShell *shell,
+ cairo_t *cr,
gint x,
gint y,
gint w,
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index c72310a..d8a3870 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -289,9 +289,9 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->x_src_dec = 1;
shell->y_src_dec = 1;
- shell->render_buf = g_new (guchar,
- GIMP_DISPLAY_RENDER_BUF_WIDTH *
- GIMP_DISPLAY_RENDER_BUF_HEIGHT * 3);
+ shell->render_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ GIMP_DISPLAY_RENDER_BUF_WIDTH,
+ GIMP_DISPLAY_RENDER_BUF_HEIGHT);
shell->icon_size = 32;
@@ -868,10 +868,10 @@ gimp_display_shell_destroy (GtkObject *object)
shell->filter_idle_id = 0;
}
- if (shell->render_buf)
+ if (shell->render_surface)
{
- g_free (shell->render_buf);
- shell->render_buf = NULL;
+ cairo_surface_destroy (shell->render_surface);
+ shell->render_surface = NULL;
}
if (shell->highlight)
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index bfd4d98..63a6e24 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -131,7 +131,7 @@ struct _GimpDisplayShell
GtkWidget *statusbar; /* statusbar */
- guchar *render_buf; /* buffer for rendering the image */
+ cairo_surface_t *render_surface; /* buffer for rendering the image */
guint title_idle_id; /* title update idle ID */
gchar *title; /* current title */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]