[Rawstudio-commit] r1502 - trunk/src
Anders Brander
anders at brander.dk
Tue Nov 27 23:22:14 CET 2007
Author: abrander
Date: 2007-11-27 23:22:14 +0100 (Tue, 27 Nov 2007)
New Revision: 1502
Modified:
trunk/src/rs-histogram.c
Log:
Updated histogram with modern Cairo-based drawing and a luminance curve.
Modified: trunk/src/rs-histogram.c
===================================================================
--- trunk/src/rs-histogram.c 2007-11-27 18:05:57 UTC (rev 1501)
+++ trunk/src/rs-histogram.c 2007-11-27 22:22:14 UTC (rev 1502)
@@ -26,11 +26,11 @@
GtkDrawingArea parent;
gint width;
gint height;
- guchar *buffer;
+ GdkPixmap *blitter;
RS_IMAGE16 *image;
RS_COLOR_TRANSFORM *rct;
guint input_samples[4][256];
- guint *output_samples[3];
+ guint *output_samples[4];
};
struct _RSHistogramWidgetClass
@@ -66,9 +66,10 @@
hist->output_samples[0] = NULL;
hist->output_samples[1] = NULL;
hist->output_samples[2] = NULL;
+ hist->output_samples[3] = NULL;
hist->image = NULL;
hist->rct = NULL;
- hist->buffer = NULL;
+ hist->blitter = NULL;
g_signal_connect(G_OBJECT(hist), "size-allocate", G_CALLBACK(size_allocate), NULL);
}
@@ -84,17 +85,19 @@
histogram->height = allocation->height;
/* Free the samples array if needed */
- for (c=0;c<3;c++)
+ for (c=0;c<4;c++)
{
if (histogram->output_samples[c])
g_free(histogram->output_samples[c]);
histogram->output_samples[c] = NULL;
}
- /* Free buffer if needed */
- if (histogram->buffer)
- g_free(histogram->buffer);
- histogram->buffer = NULL;
+ /* Free blitter if needed */
+ if (histogram->blitter)
+ {
+ g_object_unref(histogram->blitter);
+ histogram->blitter = NULL;
+ }
}
static gboolean
@@ -153,11 +156,13 @@
void
rs_histogram_redraw(RSHistogramWidget *histogram)
{
- gint c, x, y;
+ gint c, x;
guint max;
GdkDrawable *window;
GtkWidget *widget;
GdkGC *gc;
+ const static GdkColor bg = {0, 0x9900, 0x9900, 0x9900};
+ const static GdkColor lines = {0, 0x7700, 0x7700, 0x7700};
g_return_if_fail (RS_IS_HISTOGRAM_WIDGET(histogram));
@@ -166,23 +171,19 @@
gc = gdk_gc_new(window);
/* Allocate new buffer if needed */
- if (histogram->buffer == NULL)
- histogram->buffer = g_new(guchar, histogram->width * histogram->height * 3);
+ if (histogram->blitter == NULL)
+ histogram->blitter = gdk_pixmap_new(window, histogram->width, histogram->height, -1);
/* Reset background to a nice grey */
- memset(histogram->buffer, 0x99, histogram->width*histogram->height*3);
+ gdk_gc_set_rgb_fg_color(gc, &bg);
+ gdk_draw_rectangle(histogram->blitter, gc, TRUE, 0, 0, histogram->width, histogram->height);
/* Draw vertical lines */
- gint dist = (gint) ((gfloat)histogram->width / 4.0f);
- for(y=0;y<histogram->height;y++)
- {
- for(x=dist;x<histogram->width;x+=dist)
- {
- histogram->buffer[(y*histogram->width+x)*3] = 0x77;
- histogram->buffer[(y*histogram->width+x)*3+1] = 0x77;
- histogram->buffer[(y*histogram->width+x)*3+2] = 0x77;
- }
- }
+ gdk_gc_set_rgb_fg_color(gc, &lines);
+ gdk_draw_line(histogram->blitter, gc, histogram->width*0.25, 0, histogram->width*0.25, histogram->height-1);
+ gdk_draw_line(histogram->blitter, gc, histogram->width*0.5, 0, histogram->width*0.5, histogram->height-1);
+ gdk_draw_line(histogram->blitter, gc, histogram->width*0.75, 0, histogram->width*0.75, histogram->height-1);
+
/* Draw histogram if we got everything needed */
if (histogram->rct && histogram->image && (GTK_WIDGET_VISIBLE(widget)))
{
@@ -191,7 +192,7 @@
/* Interpolate data for correct width and find maximum value */
max = 0;
- for (c=0;c<3;c++)
+ for (c=0;c<4;c++)
histogram->output_samples[c] = interpolate_dataset_int(
&histogram->input_samples[c][1], 253,
histogram->output_samples[c], histogram->width,
@@ -200,31 +201,123 @@
/* Find the scaling factor */
gfloat factor = (gfloat)(max+histogram->height)/(gfloat)histogram->height;
- /* Draw everything */
+#if GTK_CHECK_VERSION(2,18,0)
+ cairo_t *cr;
+
+ /* We will use Cairo for this if possible */
+ cr = gdk_cairo_create (histogram->blitter);
+
+ /* Line width */
+ cairo_set_line_width (cr, 2.0);
+
+ /* Red */
+ cairo_set_source_rgba(cr, 1.0, 0.2, 0.2, 1.0);
+ /* Start at first column */
+ cairo_move_to (cr, 0, (histogram->height-1)-histogram->output_samples[0][0]/factor);
+ /* Walk through columns */
+ for (x = 1; x < histogram->width; x++)
+ cairo_line_to(cr, x, (histogram->height-1)-histogram->output_samples[0][x]/factor);
+ /* Draw the line */
+ cairo_stroke (cr);
+
+ /* Underexposed */
+ cairo_set_source_rgba(cr, 1.0, 0.2, 0.2, histogram->input_samples[0][0]/100.0);
+ cairo_arc(cr, 8.0, 8.0, 3.0, 0.0, 2*M_PI);
+ cairo_fill(cr);
+
+ /* Overexposed */
+ cairo_set_source_rgba(cr, 1.0, 0.2, 0.2, histogram->input_samples[0][255]/100.0);
+ cairo_arc(cr, histogram->width-8.0, 8.0, 3.0, 0.0, 2*M_PI);
+ cairo_fill(cr);
+
+ /* Green */
+ cairo_set_source_rgba(cr, 0.2, 1.0, 0.2, 0.5);
+ cairo_move_to (cr, 0, (histogram->height-1)-histogram->output_samples[1][0]/factor);
+ for (x = 1; x < histogram->width; x++)
+ cairo_line_to(cr, x, (histogram->height-1)-histogram->output_samples[1][x]/factor);
+ cairo_stroke (cr);
+ cairo_set_source_rgba(cr, 0.2, 1.0, 0.2, histogram->input_samples[1][0]/100.0);
+ cairo_arc(cr, 8.0, 16.0, 3.0, 0.0, 2*M_PI);
+ cairo_fill(cr);
+ cairo_set_source_rgba(cr, 0.2, 1.0, 0.2, histogram->input_samples[1][255]/100.0);
+ cairo_arc(cr, histogram->width-8.0, 16.0, 3.0, 0.0, 2*M_PI);
+ cairo_fill(cr);
+
+ /* Blue */
+ cairo_set_source_rgba(cr, 0.2, 0.2, 1.0, 0.5);
+ cairo_move_to (cr, 0, (histogram->height-1)-histogram->output_samples[2][0]/factor);
+ for (x = 1; x < histogram->width; x++)
+ cairo_line_to(cr, x, (histogram->height-1)-histogram->output_samples[2][x]/factor);
+ cairo_stroke (cr);
+ cairo_set_source_rgba(cr, 0.2, 0.2, 1.0, histogram->input_samples[2][0]/100.0);
+ cairo_arc(cr, 8.0, 24.0, 3.0, 0.0, 2*M_PI);
+ cairo_fill(cr);
+ cairo_set_source_rgba(cr, 0.2, 0.2, 1.0, histogram->input_samples[2][255]/100.0);
+ cairo_arc(cr, histogram->width-8.0, 24.0, 3.0, 0.0, 2*M_PI);
+ cairo_fill(cr);
+
+ /* Luma */
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5);
+ cairo_move_to (cr, 0, histogram->height);
for (x = 0; x < histogram->width; x++)
- for (c = 0; c < 3; c++)
- for (y = 0; y < (histogram->output_samples[c][x]/factor); y++)
- (histogram->buffer + ((histogram->height-1)-y) * histogram->width*3 + x * 3)[c] =0xFF;
+ cairo_line_to(cr, x, (histogram->height)-histogram->output_samples[3][x]/factor);
+ cairo_line_to(cr, x, histogram->height);
+ cairo_fill (cr);
- /* draw under/over-exposed indicators */
- for (c = 0; c < 3; c++)
+ /* We're done */
+ cairo_destroy (cr);
+#else /* GTK_CHECK_VERSION(2,8,0) */
+ GdkPoint points[histogram->width];
+ const static GdkColor red = {0, 0xffff, 0x0000, 0x0000 };
+ const static GdkColor green = {0, 0x0000, 0xffff, 0x0000 };
+ const static GdkColor blue = {0, 0x0000, 0x0000, 0xffff };
+ const static GdkColor luma = {0, 0xeeee, 0xeeee, 0xeeee };
+
+ /* Red */
+ gdk_gc_set_rgb_fg_color(gc, &red);
+ for (x = 0; x < histogram->width; x++)
{
- if (histogram->input_samples[c][0] > 100)
- for(y = 0; y < 10; y++)
- for(x = 0; x < (10-y); x++)
- histogram->buffer[y*histogram->width*3 + x*3+c] = 0xFF;
+ points[x].x = x; /* Only update x the first time! */
+ points[x].y = (histogram->height-1)-histogram->output_samples[0][x]/factor;
+ }
+ gdk_draw_lines(histogram->blitter, gc, points, histogram->width);
+ /* Underexposed */
+ if (histogram->input_samples[0][0]>99)
+ gdk_draw_arc(histogram->blitter, gc, TRUE, 1, 0, 8, 8, 0, 360*64);
+ /* Overexposed */
+ if (histogram->input_samples[0][255]>99)
+ gdk_draw_arc(histogram->blitter, gc, TRUE, histogram->width-10, 0, 8, 8, 0, 360*64);
- if (histogram->input_samples[c][255] > 100)
- for(y = 0; y < 10; y++)
- for(x = (histogram->width-10+y); x < histogram->width; x++)
- histogram->buffer[y*histogram->width*3 + x*3+c] = 0xFF;
- }
+ /* Green */
+ gdk_gc_set_rgb_fg_color(gc, &green);
+ for (x = 0; x < histogram->width; x++)
+ points[x].y = (histogram->height-1)-histogram->output_samples[1][x]/factor;
+ gdk_draw_lines(histogram->blitter, gc, points, histogram->width);
+ if (histogram->input_samples[1][0]>99)
+ gdk_draw_arc(histogram->blitter, gc, TRUE, 1, 10, 8, 8, 0, 360*64);
+ if (histogram->input_samples[1][255]>99)
+ gdk_draw_arc(histogram->blitter, gc, TRUE, histogram->width-10, 10, 8, 8, 0, 360*64);
+
+ /* Blue */
+ gdk_gc_set_rgb_fg_color(gc, &blue);
+ for (x = 0; x < histogram->width; x++)
+ points[x].y = (histogram->height-1)-histogram->output_samples[2][x]/factor;
+ gdk_draw_lines(histogram->blitter, gc, points, histogram->width);
+ if (histogram->input_samples[2][0]>99)
+ gdk_draw_arc(histogram->blitter, gc, TRUE, 1, 20, 8, 8, 0, 360*64);
+ if (histogram->input_samples[2][255]>99)
+ gdk_draw_arc(histogram->blitter, gc, TRUE, histogram->width-10, 20, 8, 8, 0, 360*64);
+
+ /* Luma */
+ gdk_gc_set_rgb_fg_color(gc, &luma);
+ for (x = 0; x < histogram->width; x++)
+ points[x].y = (histogram->height-1)-histogram->output_samples[3][x]/factor;
+ gdk_draw_lines(histogram->blitter, gc, points, histogram->width);
+#endif /* GTK_CHECK_VERSION(2,8,0) */
}
/* Blit to screen */
- gdk_draw_rgb_image(window, gc,
- 0, 0, histogram->width, histogram->height, GDK_RGB_DITHER_NONE,
- histogram->buffer, histogram->width*3);
+ gdk_draw_drawable(window, gc, histogram->blitter, 0, 0, 0, 0, histogram->width, histogram->height);
g_object_unref(gc);
}
More information about the Rawstudio-commit
mailing list