[gimp] plug-ins: port Lighting Effects to cairo
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: port Lighting Effects to cairo
- Date: Tue, 2 Nov 2010 20:34:36 +0000 (UTC)
commit 81fee76747391091e26079926e17ac20a50415a6
Author: Mikael Magnusson <mikachu gmail com>
Date: Sun Oct 31 19:03:18 2010 +0100
plug-ins: port Lighting Effects to cairo
plug-ins/lighting/lighting-image.c | 13 +++-
plug-ins/lighting/lighting-image.h | 7 ++-
plug-ins/lighting/lighting-preview.c | 154 +++++++++++++++++----------------
plug-ins/lighting/lighting-preview.h | 10 --
plug-ins/lighting/lighting-ui.c | 6 +-
plug-ins/lighting/lighting-ui.h | 1 -
6 files changed, 101 insertions(+), 90 deletions(-)
---
diff --git a/plug-ins/lighting/lighting-image.c b/plug-ins/lighting/lighting-image.c
index 2091441..99b0b6f 100644
--- a/plug-ins/lighting/lighting-image.c
+++ b/plug-ins/lighting/lighting-image.c
@@ -23,7 +23,9 @@ GimpPixelRgn bump_region;
GimpDrawable *env_drawable = NULL;
GimpPixelRgn env_region;
-guchar *preview_rgb_data = NULL;
+guchar *preview_rgb_data = NULL;
+gint preview_rgb_stride;
+cairo_surface_t *preview_surface = NULL;
glong maxcounter;
gint imgtype, width, height, env_width, env_height, in_channels, out_channels;
@@ -373,7 +375,14 @@ image_setup (GimpDrawable *drawable,
if (interactive)
{
- preview_rgb_data = g_new0 (guchar, PREVIEW_WIDTH * PREVIEW_HEIGHT * 3);
+ preview_rgb_stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24,
+ PREVIEW_WIDTH);
+ preview_rgb_data = g_new0 (guchar, preview_rgb_stride * PREVIEW_HEIGHT);
+ preview_surface = cairo_image_surface_create_for_data (preview_rgb_data,
+ CAIRO_FORMAT_RGB24,
+ PREVIEW_WIDTH,
+ PREVIEW_HEIGHT,
+ preview_rgb_stride);
}
return TRUE;
diff --git a/plug-ins/lighting/lighting-image.h b/plug-ins/lighting/lighting-image.h
index a2ab26a..a7f3dc9 100644
--- a/plug-ins/lighting/lighting-image.h
+++ b/plug-ins/lighting/lighting-image.h
@@ -1,6 +1,9 @@
#ifndef __LIGHTING_IMAGE_H__
#define __LIGHTING_IMAGE_H__
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
extern GimpDrawable *input_drawable,*output_drawable;
extern GimpPixelRgn source_region, dest_region;
@@ -10,7 +13,9 @@ extern GimpPixelRgn bump_region;
extern GimpDrawable *env_drawable;
extern GimpPixelRgn env_region;
-extern guchar *preview_rgb_data;
+extern guchar *preview_rgb_data;
+extern gint preview_rgb_stride;
+extern cairo_surface_t *preview_surface;
extern glong maxcounter;
extern gint imgtype,width,height,env_width,env_height,in_channels,out_channels;
diff --git a/plug-ins/lighting/lighting-preview.c b/plug-ins/lighting/lighting-preview.c
index 32f456b..e647c92 100644
--- a/plug-ins/lighting/lighting-preview.c
+++ b/plug-ins/lighting/lighting-preview.c
@@ -20,9 +20,15 @@
#define LIGHT_SYMBOL_SIZE 8
+typedef struct
+{
+ gint x, y, w, h;
+ cairo_surface_t *image;
+} BackBuffer;
+
static gint handle_xpos = 0, handle_ypos = 0;
-BackBuffer backbuf = { 0, 0, 0, 0, NULL };
+static BackBuffer backbuf = { 0, 0, 0, 0, NULL };
/* g_free()'ed on exit */
gdouble *xpostab = NULL;
@@ -31,8 +37,8 @@ gdouble *ypostab = NULL;
static gint xpostab_size = -1; /* if preview size change, do realloc */
static gint ypostab_size = -1;
-gboolean light_hit = FALSE;
-gboolean left_button_pressed = FALSE;
+static gboolean light_hit = FALSE;
+static gboolean left_button_pressed = FALSE;
static guint preview_update_timer = 0;
@@ -45,6 +51,7 @@ static void
compute_preview (gint startx, gint starty, gint w, gint h)
{
gint xcnt, ycnt, f1, f2;
+ guchar r, g, b;
gdouble imagex, imagey;
gint32 index = 0;
GimpRGB color;
@@ -124,8 +131,11 @@ compute_preview (gint startx, gint starty, gint w, gint h)
ray_func = get_ray_color_no_bilinear_ref;
}
+ cairo_surface_flush (preview_surface);
+
for (ycnt = 0; ycnt < PREVIEW_HEIGHT; ycnt++)
{
+ index = ycnt * preview_rgb_stride;
for (xcnt = 0; xcnt < PREVIEW_WIDTH; xcnt++)
{
if ((ycnt >= starty && ycnt < (starty + h)) &&
@@ -171,13 +181,9 @@ compute_preview (gint startx, gint starty, gint w, gint h)
}
}
- gimp_rgb_get_uchar (&color,
- preview_rgb_data + index,
- preview_rgb_data + index +
- 1,
- preview_rgb_data + index +
- 2);
- index += 3;
+ gimp_rgb_get_uchar (&color, &r, &g, &b);
+ GIMP_CAIRO_RGB24_SET_PIXEL((preview_rgb_data + index), r, g, b);
+ index += 4;
imagex++;
}
else
@@ -185,9 +191,11 @@ compute_preview (gint startx, gint starty, gint w, gint h)
preview_rgb_data[index++] = 200;
preview_rgb_data[index++] = 200;
preview_rgb_data[index++] = 200;
+ index++;
}
}
}
+ cairo_surface_mark_dirty (preview_surface);
}
static void
@@ -296,22 +304,28 @@ draw_handles (void)
break;
}
- gdk_gc_set_function (gc, GDK_COPY);
-
if (mapvals.lightsource[k].type != NO_LIGHT)
{
GdkColor color;
+ cairo_t *cr;
+ cr = gdk_cairo_create (gtk_widget_get_window (previewarea));
+
+ cairo_set_line_width (cr, 1.0);
/* Restore background if it has been saved */
/* ======================================= */
if (backbuf.image != NULL)
{
- gdk_gc_set_function (gc, GDK_COPY);
- gdk_draw_image (gtk_widget_get_window (previewarea), gc,
- backbuf.image, 0, 0, backbuf.x,
- backbuf.y, backbuf.w, backbuf.h);
- g_object_unref (backbuf.image);
+ cairo_rectangle (cr, backbuf.x, backbuf.y, backbuf.w, backbuf.h);
+ cairo_clip (cr);
+ cairo_set_source_surface (cr, backbuf.image, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (backbuf.image);
+ cairo_reset_clip (cr);
+ cairo_rectangle (cr, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT);
+ cairo_clip (cr);
backbuf.image = NULL;
}
@@ -319,10 +333,10 @@ draw_handles (void)
switch (mapvals.lightsource[k].type)
{
case POINT_LIGHT:
- backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2;
- backbuf.y = handle_ypos - LIGHT_SYMBOL_SIZE / 2;
- backbuf.w = LIGHT_SYMBOL_SIZE;
- backbuf.h = LIGHT_SYMBOL_SIZE;
+ backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2 - 1;
+ backbuf.y = handle_ypos - LIGHT_SYMBOL_SIZE / 2 - 1;
+ backbuf.w = LIGHT_SYMBOL_SIZE + 2;
+ backbuf.h = LIGHT_SYMBOL_SIZE + 2;
break;
case DIRECTIONAL_LIGHT:
if (delta_x <= 0)
@@ -333,16 +347,16 @@ draw_handles (void)
backbuf.y = handle_ypos;
else
backbuf.y = starty + ph/2;
- backbuf.x -= LIGHT_SYMBOL_SIZE/2;
- backbuf.y -= LIGHT_SYMBOL_SIZE/2;
- backbuf.w = fabs(delta_x) + LIGHT_SYMBOL_SIZE;
- backbuf.h = fabs(delta_y) + LIGHT_SYMBOL_SIZE;
+ backbuf.x -= LIGHT_SYMBOL_SIZE/2 + 1;
+ backbuf.y -= LIGHT_SYMBOL_SIZE/2 + 1;
+ backbuf.w = fabs(delta_x) + LIGHT_SYMBOL_SIZE + 2;
+ backbuf.h = fabs(delta_y) + LIGHT_SYMBOL_SIZE + 2;
break;
case SPOT_LIGHT:
- backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2;
- backbuf.y = handle_ypos - LIGHT_SYMBOL_SIZE / 2;
- backbuf.w = LIGHT_SYMBOL_SIZE;
- backbuf.h = LIGHT_SYMBOL_SIZE;
+ backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2 - 1;
+ backbuf.y = handle_ypos - LIGHT_SYMBOL_SIZE / 2 - 1;
+ backbuf.w = LIGHT_SYMBOL_SIZE + 2;
+ backbuf.h = LIGHT_SYMBOL_SIZE + 2;
break;
case NO_LIGHT:
break;
@@ -350,10 +364,17 @@ draw_handles (void)
/* Save background */
/* =============== */
- if ((backbuf.x >= 0) &&
+ if ((backbuf.x + backbuf.w >= 0) &&
(backbuf.x <= PREVIEW_WIDTH) &&
- (backbuf.y >= 0) && (backbuf.y <= PREVIEW_HEIGHT))
+ (backbuf.y + backbuf.h >= 0) && (backbuf.y <= PREVIEW_HEIGHT))
{
+ cairo_t *cr;
+
+ backbuf.image = cairo_surface_create_similar (preview_surface,
+ CAIRO_CONTENT_COLOR,
+ PREVIEW_WIDTH,
+ PREVIEW_HEIGHT);
+ cr = cairo_create (backbuf.image);
/* clip coordinates to preview widget sizes */
if ((backbuf.x + backbuf.w) > PREVIEW_WIDTH)
backbuf.w = (PREVIEW_WIDTH - backbuf.x);
@@ -361,44 +382,44 @@ draw_handles (void)
if ((backbuf.y + backbuf.h) > PREVIEW_HEIGHT)
backbuf.h = (PREVIEW_HEIGHT - backbuf.y);
- backbuf.image = gdk_drawable_get_image (gtk_widget_get_window (previewarea),
- backbuf.x, backbuf.y,
- backbuf.w, backbuf.h);
+ cairo_rectangle (cr, backbuf.x, backbuf.y, backbuf.w, backbuf.h);
+ cairo_clip (cr);
+ cairo_set_source_surface (cr, preview_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
}
color.red = 0x0;
color.green = 0x0;
color.blue = 0x0;
- gdk_gc_set_rgb_bg_color (gc, &color);
+ gdk_cairo_set_source_color (cr, &color);
color.red = 0x0;
color.green = 0x4000;
color.blue = 0xFFFF;
- gdk_gc_set_rgb_fg_color (gc, &color);
+ gdk_cairo_set_source_color (cr, &color);
/* draw circle at light position */
switch (mapvals.lightsource[k].type)
{
case POINT_LIGHT:
case SPOT_LIGHT:
- gdk_draw_arc (gtk_widget_get_window (previewarea), gc, TRUE,
- handle_xpos - LIGHT_SYMBOL_SIZE / 2,
- handle_ypos - LIGHT_SYMBOL_SIZE / 2,
- LIGHT_SYMBOL_SIZE,
- LIGHT_SYMBOL_SIZE, 0, 360 * 64);
+ cairo_arc (cr, handle_xpos, handle_ypos,
+ LIGHT_SYMBOL_SIZE/2, 0, 2 * M_PI);
+ cairo_fill (cr);
break;
case DIRECTIONAL_LIGHT:
- gdk_draw_arc (gtk_widget_get_window (previewarea), gc, TRUE,
- handle_xpos - LIGHT_SYMBOL_SIZE / 2,
- handle_ypos - LIGHT_SYMBOL_SIZE / 2,
- LIGHT_SYMBOL_SIZE,
- LIGHT_SYMBOL_SIZE, 0, 360 * 64);
- gdk_draw_line (gtk_widget_get_window (previewarea), gc,
- handle_xpos, handle_ypos, startx+pw/2 , starty + ph/2);
+ cairo_arc (cr, handle_xpos, handle_ypos,
+ LIGHT_SYMBOL_SIZE/2, 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_move_to (cr, handle_xpos, handle_ypos);
+ cairo_line_to (cr, startx + pw/2, starty + ph/2);
+ cairo_stroke (cr);
break;
case NO_LIGHT:
break;
}
+ cairo_destroy (cr);
}
}
@@ -450,19 +471,7 @@ void
draw_preview_image (gboolean recompute)
{
gint startx, starty, pw, ph;
- GdkColor color;
-
- color.red = 0x0;
- color.green = 0x0;
- color.blue = 0x0;
- gdk_gc_set_rgb_bg_color (gc, &color);
-
- color.red = 0xFFFF;
- color.green = 0xFFFF;
- color.blue = 0xFFFF;
- gdk_gc_set_rgb_fg_color (gc, &color);
-
- gdk_gc_set_function (gc, GDK_COPY);
+ cairo_t *cr;
compute_preview_rectangle (&startx, &starty, &pw, &ph);
@@ -486,15 +495,18 @@ draw_preview_image (gboolean recompute)
* restore the wrong bitmap */
if (backbuf.image != NULL)
{
- g_object_unref (backbuf.image);
+ cairo_surface_destroy (backbuf.image);
backbuf.image = NULL;
}
}
- gdk_draw_rgb_image (gtk_widget_get_window (previewarea), gc,
- 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT,
- GDK_RGB_DITHER_MAX, preview_rgb_data,
- 3 * PREVIEW_WIDTH);
+ cr = gdk_cairo_create (gtk_widget_get_window (previewarea));
+
+ cairo_set_source_surface (cr, preview_surface, 0.0, 0.0);
+
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
/* draw symbols if enabled in UI */
if (mapvals.interactive_preview)
@@ -515,15 +527,7 @@ preview_events (GtkWidget *area,
{
case GDK_EXPOSE:
- /* Is this the first exposure? */
- /* =========================== */
- if (!gc)
- {
- gc = gdk_gc_new (gtk_widget_get_window (area));
- draw_preview_image (TRUE);
- }
- else
- draw_preview_image (FALSE);
+ draw_preview_image (FALSE);
break;
case GDK_ENTER_NOTIFY:
break;
diff --git a/plug-ins/lighting/lighting-preview.h b/plug-ins/lighting/lighting-preview.h
index 1a1974a..d1698e6 100644
--- a/plug-ins/lighting/lighting-preview.h
+++ b/plug-ins/lighting/lighting-preview.h
@@ -20,19 +20,9 @@
#define PREVIEW_WIDTH 200
#define PREVIEW_HEIGHT 200
-typedef struct
-{
- gint x, y, w, h;
- GdkImage *image;
-} BackBuffer;
-
/* Externally visible variables */
-extern gint lightx, lighty;
-extern BackBuffer backbuf;
extern gdouble *xpostab, *ypostab;
-extern gboolean light_hit;
-extern gboolean left_button_pressed;
/* Externally visible functions */
diff --git a/plug-ins/lighting/lighting-ui.c b/plug-ins/lighting/lighting-ui.c
index 123ef05..99fb348 100644
--- a/plug-ins/lighting/lighting-ui.c
+++ b/plug-ins/lighting/lighting-ui.c
@@ -41,7 +41,6 @@ extern LightingValues mapvals;
static GtkWidget *appwin = NULL;
static GtkNotebook *options_note_book = NULL;
-GdkGC *gc = NULL;
GtkWidget *previewarea = NULL;
GtkWidget *spin_pos_x = NULL;
@@ -1112,12 +1111,17 @@ main_dialog (GimpDrawable *drawable)
image_setup (drawable, TRUE);
+ draw_preview_image (TRUE);
+
if (gimp_dialog_run (GIMP_DIALOG (appwin)) == GTK_RESPONSE_OK)
run = TRUE;
if (preview_rgb_data != NULL)
g_free (preview_rgb_data);
+ if (preview_surface != NULL)
+ cairo_surface_destroy (preview_surface);
+
gtk_widget_destroy (appwin);
return run;
diff --git a/plug-ins/lighting/lighting-ui.h b/plug-ins/lighting/lighting-ui.h
index 3e89532..904aae8 100644
--- a/plug-ins/lighting/lighting-ui.h
+++ b/plug-ins/lighting/lighting-ui.h
@@ -4,7 +4,6 @@
/* Externally visible variables */
/* ============================ */
-extern GdkGC *gc;
extern GtkWidget *previewarea;
extern GtkWidget *spin_pos_x;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]