From d98d7e1529ddf0e7f5430b43cd79dba8858b6284 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Fri, 21 Dec 2012 19:42:09 +0000 Subject: Use cairo surface for ruler widget - minimise delta against GTK+ 3 builds (bzr r11965) --- src/widgets/ruler.cpp | 54 ++++++++++++--------------------------------------- 1 file changed, 12 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 5104d5a9d..929bf34da 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -37,11 +37,7 @@ struct _SPRulerPrivate GtkOrientation orientation; SPRulerMetric *metric; -#if GTK_CHECK_VERSION(3,0,0) cairo_surface_t *backing_store; -#else - GdkPixmap *backing_store; -#endif gint slider_size; gint xsrc; @@ -443,11 +439,7 @@ static void sp_ruler_draw_ticks(SPRuler *ruler) g_return_if_fail(SP_IS_RULER(ruler)); SPRulerPrivate *priv = ruler->priv; -#if GTK_CHECK_VERSION(3,0,0) cairo_t *cr = cairo_create(priv->backing_store); -#else - cairo_t *cr = gdk_cairo_create(priv->backing_store); -#endif if (SP_RULER_GET_CLASS(ruler)->draw_ticks) SP_RULER_GET_CLASS(ruler)->draw_ticks(ruler, cr); @@ -508,11 +500,7 @@ static void sp_ruler_unrealize(GtkWidget *widget) if (priv->backing_store) { -#if GTK_CHECK_VERSION(3,0,0) cairo_surface_destroy(priv->backing_store); -#else - g_object_unref(priv->backing_store); -#endif priv->backing_store = NULL; } @@ -586,16 +574,15 @@ static gboolean sp_ruler_expose(GtkWidget *widget, SPRuler *ruler = SP_RULER (widget); SPRulerPrivate *priv = ruler->priv; -#if GTK_CHECK_VERSION(3,0,0) - cairo_set_source_surface(cr, priv->backing_store, 0, 0); - cairo_paint(cr); -#else +#if !GTK_CHECK_VERSION(3,0,0) cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); - gdk_cairo_set_source_pixmap(cr, priv->backing_store, 0, 0); gdk_cairo_region(cr, event->region); - cairo_fill(cr); + cairo_clip(cr); #endif + cairo_set_source_surface(cr, priv->backing_store, 0, 0); + cairo_paint(cr); + if (SP_RULER_GET_CLASS(ruler)->draw_pos) SP_RULER_GET_CLASS(ruler)->draw_pos(ruler, cr); @@ -615,21 +602,12 @@ static void sp_ruler_make_pixmap(SPRuler *ruler) gtk_widget_get_allocation(widget, &allocation); if (priv->backing_store) -#if GTK_CHECK_VERSION(3,0,0) cairo_surface_destroy(priv->backing_store); priv->backing_store = gdk_window_create_similar_surface(gtk_widget_get_window(widget), CAIRO_CONTENT_COLOR, allocation.width, allocation.height); -#else - g_object_unref(priv->backing_store); - - priv->backing_store = gdk_pixmap_new(gtk_widget_get_window(widget), - allocation.width, - allocation.height, - -1); -#endif priv->xsrc = 0; priv->ysrc = 0; @@ -802,27 +780,19 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) } #if GTK_CHECK_VERSION(3,0,0) - gtk_render_frame(context, - cr, - 0, 0, - allocation.width, allocation.height); - - gtk_render_background(context, - cr, - 0, 0, - allocation.width, allocation.height); + GdkRGBA color; + gtk_style_context_get_background_color(context, + gtk_widget_get_state_flags(widget), + &color); + gdk_cairo_set_source_rgba(cr, &color); #else - gtk_paint_box(style, priv->backing_store, - GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, - orientation == GTK_ORIENTATION_HORIZONTAL ? "hruler" : "vruler", - 0, 0, - allocation.width, allocation.height); + gdk_cairo_set_source_color(cr, &style->bg[gtk_widget_get_state(widget)]); #endif + cairo_paint(cr); cairo_set_line_width(cr, 1.0); #if GTK_CHECK_VERSION(3,0,0) - GdkRGBA color; gtk_style_context_get_color(context, gtk_widget_get_state_flags(widget), &color); -- cgit v1.2.3 From add6f499fe1d40d0f473c09e17165b0a481a0f43 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 22 Dec 2012 13:09:26 +0000 Subject: ruler: Add modeline support (bzr r11966) --- src/widgets/ruler.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 929bf34da..a2cb46e01 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -927,3 +927,14 @@ void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric) sp_ruler_invalidate_ticks(ruler); } + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 50f7f19e58e4c8db48a3fc2b3e0831a803c7fd3b Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 22 Dec 2012 15:32:34 +0000 Subject: ruler: Remove draw_ticks from public API (bzr r11967) --- src/widgets/ruler.cpp | 83 +++++++++++++++++++++++++-------------------------- src/widgets/ruler.h | 2 -- 2 files changed, 40 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index a2cb46e01..0a052d1dc 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -95,8 +95,6 @@ static gboolean sp_ruler_expose (GtkWidget *widget, #endif static void sp_ruler_make_pixmap (SPRuler *ruler); static void sp_ruler_draw_ticks (SPRuler *ruler); -static void sp_ruler_real_draw_ticks (SPRuler *ruler, - cairo_t *cr); static void sp_ruler_real_draw_pos (SPRuler *ruler, cairo_t *cr); @@ -143,7 +141,6 @@ sp_ruler_class_init (SPRulerClass *klass) widget_class->size_allocate = sp_ruler_size_allocate; widget_class->motion_notify_event = sp_ruler_motion_notify; - klass->draw_ticks = sp_ruler_real_draw_ticks; klass->draw_pos = sp_ruler_real_draw_pos; g_object_class_override_property (gobject_class, @@ -434,20 +431,6 @@ SPMetric sp_ruler_get_metric(SPRuler *ruler) } -static void sp_ruler_draw_ticks(SPRuler *ruler) -{ - g_return_if_fail(SP_IS_RULER(ruler)); - SPRulerPrivate *priv = ruler->priv; - - cairo_t *cr = cairo_create(priv->backing_store); - - if (SP_RULER_GET_CLASS(ruler)->draw_ticks) - SP_RULER_GET_CLASS(ruler)->draw_ticks(ruler, cr); - - cairo_destroy(cr); -} - - static void sp_ruler_realize(GtkWidget *widget) { GtkAllocation allocation; @@ -732,20 +715,32 @@ static gboolean sp_ruler_motion_notify(GtkWidget *widget, return FALSE; } -static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) +static void sp_ruler_draw_ticks(SPRuler *ruler) { - SPRulerPrivate *priv = ruler->priv; - gint width = 0; - gint height = 0; - gchar unit_str[32]; - gchar digit_str[2] = { '\0', '\0' }; - GtkOrientation orientation; - GtkAllocation allocation; + GtkWidget *widget = GTK_WIDGET (ruler); + +#if GTK_CHECK_VERSION(3,0,0) + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkStateFlags state = gtk_widget_get_state_flags (widget); +#else + GtkStyle *style = gtk_widget_get_style (widget); + GtkStateType state = gtk_widget_get_state (widget); +#endif + + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + cairo_t *cr = cairo_create(priv->backing_store); + gint width = 0; + gint height = 0; + gint length; + gdouble increment; /* Number of pixels per unit */ + gint scale; /* Number of units per major unit */ + gchar unit_str[32]; + gchar digit_str[2] = { '\0', '\0' }; + gint text_size; g_return_if_fail (ruler != NULL); - g_object_get(G_OBJECT(ruler), "orientation", &orientation, NULL); - GtkWidget *widget = GTK_WIDGET (ruler); PangoContext *pango_context = gtk_widget_get_pango_context (widget); PangoLayout *pango_layout = pango_layout_new (pango_context); @@ -757,21 +752,18 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) gint digit_height = (int) floor (RULER_FONT_SIZE * RULER_FONT_VERTICAL_SPACING / PANGO_SCALE + 0.5); #if GTK_CHECK_VERSION(3,0,0) - GtkStyleContext *context = gtk_widget_get_style_context(widget); - GtkStateFlags state = gtk_widget_get_state_flags(widget); GtkBorder padding; gtk_style_context_get_padding(context, state, &padding); gint xthickness = padding.left; gint ythickness = padding.top; #else - GtkStyle *style = gtk_widget_get_style(widget); gint xthickness = style->xthickness; gint ythickness = style->ythickness; #endif gtk_widget_get_allocation (widget, &allocation); - if (orientation == GTK_ORIENTATION_HORIZONTAL) { + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { width = allocation.width; // in pixels; is apparently 2 pixels shorter than the canvas at each end height = allocation.height; } else { @@ -782,11 +774,11 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) #if GTK_CHECK_VERSION(3,0,0) GdkRGBA color; gtk_style_context_get_background_color(context, - gtk_widget_get_state_flags(widget), + state, &color); gdk_cairo_set_source_rgba(cr, &color); #else - gdk_cairo_set_source_color(cr, &style->bg[gtk_widget_get_state(widget)]); + gdk_cairo_set_source_color(cr, &style->bg[state]); #endif cairo_paint(cr); @@ -794,11 +786,11 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) #if GTK_CHECK_VERSION(3,0,0) gtk_style_context_get_color(context, - gtk_widget_get_state_flags(widget), + state, &color); gdk_cairo_set_source_rgba(cr, &color); #else - gdk_cairo_set_source_color(cr, &style->fg[gtk_widget_get_state(widget)]); + gdk_cairo_set_source_color(cr, &style->fg[state]); #endif gdouble upper = priv->upper / priv->metric->pixels_per_unit; // upper and lower are expressed in ruler units @@ -807,9 +799,9 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) * in 1/72nd's of an inch and has nothing to do with screen pixels */ if ((upper - lower) == 0) - return; + goto out; - double increment = (double) (width + 2*UNUSED_PIXELS) / (upper - lower); // screen pixels per ruler unit + increment = (gdouble) (width + 2*UNUSED_PIXELS) / (upper - lower); // screen pixels per ruler unit /* determine the scale * For vruler, use the maximum extents of the ruler to determine the largest @@ -820,19 +812,19 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) * text_width = gdk_string_width(font, unit_str), so that the result * for the scale looks consistent with an accompanying vruler */ - gint scale = (int)(ceil(priv->max_size / priv->metric->pixels_per_unit)); + scale = (gint)(ceil(priv->max_size / priv->metric->pixels_per_unit)); sprintf (unit_str, "%d", scale); - gint text_dimension = strlen (unit_str) * digit_height + 1; + text_size = strlen (unit_str) * digit_height + 1; for (scale = 0; scale < MAXIMUM_SCALES; scale++) - if (priv->metric->ruler_scale[scale] * fabs(increment) > 2 * text_dimension) + if (priv->metric->ruler_scale[scale] * fabs(increment) > 2 * text_size) break; if (scale == MAXIMUM_SCALES) scale = MAXIMUM_SCALES - 1; /* drawing starts here */ - gint length = 0; + length = 0; for (gint i = MAXIMUM_SUBDIVIDE - 1; i >= 0; i--) { double subd_incr = priv->metric->ruler_scale[scale] / priv->metric->subdivide[i]; @@ -866,7 +858,7 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) // by a pixel, and jump back on the next redraw). This is suppressed by adding 1e-9 (that's only one nanopixel ;-)) gint pos = int(Inkscape::round((cur - lower) * increment + 1e-12)) - UNUSED_PIXELS; - if (orientation == GTK_ORIENTATION_HORIZONTAL) { + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_move_to(cr, pos+0.5, height + ythickness); cairo_line_to(cr, pos+0.5, height - length + ythickness); } else { @@ -885,7 +877,7 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) else sprintf (unit_str, "%d", (int) cur); - if (orientation == GTK_ORIENTATION_HORIZONTAL) { + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { pango_layout_set_text (pango_layout, unit_str, -1); cairo_move_to(cr, pos+2, 0); pango_cairo_show_layout(cr, pango_layout); @@ -908,6 +900,11 @@ static void sp_ruler_real_draw_ticks(SPRuler *ruler, cairo_t *cr) cairo_stroke(cr); } } + + cairo_fill (cr); + +out: + cairo_destroy (cr); } diff --git a/src/widgets/ruler.h b/src/widgets/ruler.h index d4e21b300..9b43b5488 100644 --- a/src/widgets/ruler.h +++ b/src/widgets/ruler.h @@ -46,8 +46,6 @@ struct _SPRulerClass { GtkWidgetClass parent_class; - void (* draw_ticks) (SPRuler *ruler, - cairo_t *cr); void (* draw_pos) (SPRuler *ruler, cairo_t *cr); }; -- cgit v1.2.3 From 487abf292f427b36fcb8de9b6168242df309d6bb Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 22 Dec 2012 16:11:40 +0000 Subject: ruler (Merge from GIMP): Remove draw_pos from public API (bzr r11968) --- src/widgets/ruler.cpp | 160 +++++++++++++++++++++++++++++++++++--------------- src/widgets/ruler.h | 3 - 2 files changed, 113 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 0a052d1dc..54a64cb56 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -86,17 +86,15 @@ static void sp_ruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static gboolean sp_ruler_motion_notify (GtkWidget *widget, GdkEventMotion *event); -#if GTK_CHECK_VERSION(3,0,0) static gboolean sp_ruler_draw (GtkWidget *widget, cairo_t *cr); -#else +#if !GTK_CHECK_VERSION(3,0,0) static gboolean sp_ruler_expose (GtkWidget *widget, GdkEventExpose *event); #endif static void sp_ruler_make_pixmap (SPRuler *ruler); static void sp_ruler_draw_ticks (SPRuler *ruler); -static void sp_ruler_real_draw_pos (SPRuler *ruler, - cairo_t *cr); +static void sp_ruler_draw_pos (SPRuler *ruler); #define SP_RULER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SP_TYPE_RULER, SPRulerPrivate)) @@ -141,8 +139,6 @@ sp_ruler_class_init (SPRulerClass *klass) widget_class->size_allocate = sp_ruler_size_allocate; widget_class->motion_notify_event = sp_ruler_motion_notify; - klass->draw_pos = sp_ruler_real_draw_pos; - g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation"); @@ -546,32 +542,42 @@ static void sp_ruler_size_allocate(GtkWidget *widget, GtkAllocation *allocation) } } -#if GTK_CHECK_VERSION(3,0,0) -static gboolean sp_ruler_draw(GtkWidget *widget, - cairo_t *cr) -#else + +#if !GTK_CHECK_VERSION(3,0,0) static gboolean sp_ruler_expose(GtkWidget *widget, GdkEventExpose *event) -#endif { - SPRuler *ruler = SP_RULER (widget); - SPRulerPrivate *priv = ruler->priv; + cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); + GtkAllocation allocation; + + gdk_cairo_region (cr, event->region); + cairo_clip (cr); -#if !GTK_CHECK_VERSION(3,0,0) - cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); - gdk_cairo_region(cr, event->region); - cairo_clip(cr); + gtk_widget_get_allocation (widget, &allocation); + cairo_translate (cr, allocation.x, allocation.y); + + gboolean result = sp_ruler_draw (widget, cr); + + cairo_destroy (cr); + + return result; +} #endif + + +static gboolean sp_ruler_draw(GtkWidget *widget, + cairo_t *cr) +{ + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + + sp_ruler_draw_ticks (ruler); + cairo_set_source_surface(cr, priv->backing_store, 0, 0); cairo_paint(cr); - if (SP_RULER_GET_CLASS(ruler)->draw_pos) - SP_RULER_GET_CLASS(ruler)->draw_pos(ruler, cr); - -#if !GTK_CHECK_VERSION(3,0,0) - cairo_destroy (cr); -#endif + sp_ruler_draw_pos (ruler); return FALSE; } @@ -599,27 +605,48 @@ static void sp_ruler_make_pixmap(SPRuler *ruler) } -static void sp_ruler_real_draw_pos(SPRuler *ruler, - cairo_t *cr) +static void +sp_ruler_draw_pos (SPRuler *ruler) { - GtkAllocation allocation; - GtkWidget *widget = GTK_WIDGET (ruler); - SPRulerPrivate *priv = ruler->priv; - gint x, y; - gint bs_width, bs_height; - gdouble increment; + GtkWidget *widget = GTK_WIDGET (ruler); + +#if GTK_CHECK_VERSION(3,0,0) + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkBorder border; + GdkRGBA color; +#else + GtkStyle *style = gtk_widget_get_style (widget); + GtkStateType state = gtk_widget_get_state (widget); + gint xthickness; + gint ythickness; +#endif + + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + gint x, y; + gint width, height; + gint bs_width, bs_height; + + if (! gtk_widget_is_drawable (widget)) + return; - GtkStyle *style = gtk_widget_get_style(widget); gtk_widget_get_allocation(widget, &allocation); - gint xthickness = style->xthickness; - gint ythickness = style->ythickness; - gint width = allocation.width; - gint height = allocation.height; +#if GTK_CHECK_VERSION(3,0,0) + gtk_style_context_get_border (context, static_cast(0), &border); +#else + xthickness = style->xthickness; + ythickness = style->ythickness; +#endif if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - height -= ythickness * 2; + width = allocation.width; +#if GTK_CHECK_VERSION(3,0,0) + height = allocation.height - (border.top + border.bottom); +#else + height = allocation.height - ythickness * 2; +#endif bs_width = height / 2 + 2; bs_width |= 1; /* make sure it's odd */ @@ -627,7 +654,12 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, } else { - width -= xthickness * 2; +#if GTK_CHECK_VERSION(3,0,0) + width = allocation.width - (border.left + border.right); +#else + width = allocation.width - xthickness * 2; +#endif + height = allocation.height; bs_height = width / 2 + 2; bs_height |= 1; /* make sure it's odd */ @@ -636,28 +668,60 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, if ((bs_width > 0) && (bs_height > 0)) { + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget)); + gdouble lower; + gdouble upper; + gdouble position; + gdouble increment; + + cairo_rectangle (cr, + allocation.x, allocation.y, + allocation.width, allocation.height); + cairo_clip (cr); + + cairo_translate (cr, allocation.x, allocation.y); + + /* If a backing store exists, restore the ruler */ + if (priv->backing_store) + { + cairo_set_source_surface (cr, priv->backing_store, 0, 0); + cairo_rectangle (cr, priv->xsrc, priv->ysrc, bs_width, bs_height); + cairo_fill (cr); + } + + sp_ruler_get_range (ruler, &lower, &upper, &position, NULL); + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - increment = (gdouble) width / (priv->upper - priv->lower); + increment = (gdouble) width / (upper - lower); - x = ROUND ((priv->position - priv->lower) * increment) + (xthickness - bs_width) / 2 - 1; +#if GTK_CHECK_VERSION(3,0,0) + x = ROUND ((position - lower) * increment) + (border.left - bs_width) / 2 - 1; + y = (height + bs_height) / 2 + border.top; +#else + x = ROUND ((position - lower) * increment) + (xthickness - bs_width) / 2 - 1; y = (height + bs_height) / 2 + ythickness; +#endif } else { - increment = (gdouble) height / (priv->upper - priv->lower); + increment = (gdouble) height / (upper - lower); +#if GTK_CHECK_VERSION(3,0,0) + x = (width + bs_width) / 2 + border.left; + y = ROUND ((position - lower) * increment) + (border.top - bs_height) / 2 - 1; +#else x = (width + bs_width) / 2 + xthickness; - y = ROUND ((priv->position - priv->lower) * increment) + (ythickness - bs_height) / 2 - 1; + y = ROUND ((position - lower) * increment) + (ythickness - bs_height) / 2 - 1; +#endif } #if GTK_CHECK_VERSION(3,0,0) - GtkStyleContext *sc = gtk_widget_get_style_context(widget); - GdkRGBA color; - gtk_style_context_get_color(sc, gtk_widget_get_state_flags(widget), &color); - gdk_cairo_set_source_rgba(cr, &color); + gtk_style_context_get_color (context, gtk_widget_get_state_flags (widget), + &color); + gdk_cairo_set_source_rgba (cr, &color); #else - gdk_cairo_set_source_color(cr, &style->fg[gtk_widget_get_state(widget)]); + gdk_cairo_set_source_color (cr, &style->fg[state]); #endif cairo_move_to (cr, x, y); @@ -675,6 +739,8 @@ static void sp_ruler_real_draw_pos(SPRuler *ruler, cairo_fill (cr); + cairo_destroy (cr); + priv->xsrc = x; priv->ysrc = y; } diff --git a/src/widgets/ruler.h b/src/widgets/ruler.h index 9b43b5488..992d9a385 100644 --- a/src/widgets/ruler.h +++ b/src/widgets/ruler.h @@ -45,9 +45,6 @@ struct _SPRuler struct _SPRulerClass { GtkWidgetClass parent_class; - - void (* draw_pos) (SPRuler *ruler, - cairo_t *cr); }; struct _SPRulerMetric -- cgit v1.2.3 From b5f9084693aff69e3dcd26372fd1beac1426e0f8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 22 Dec 2012 17:34:31 +0100 Subject: Minor changes. (bzr r11969) --- src/attributes.cpp | 3 --- src/attributes.h | 3 --- src/display/nr-svgfonts.cpp | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index 7d6f8614d..30cf30f30 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -258,9 +258,6 @@ static SPStyleProp const props[] = { {SP_ATTR_POINTSATY, "pointsAtY"}, {SP_ATTR_POINTSATZ, "pointsAtZ"}, {SP_ATTR_LIMITINGCONEANGLE, "limitingConeAngle"}, - /*feFlood*/ - {SP_ATTR_FLOODCOLOR, "flood-color"}, - {SP_ATTR_FLOODOPACITY, "flood-opacity"}, /* SPGaussianBlur */ {SP_ATTR_STDDEVIATION, "stdDeviation"}, /*feImage*/ diff --git a/src/attributes.h b/src/attributes.h index d8eb087b2..87cd9ed45 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -258,9 +258,6 @@ enum SPAttributeEnum { SP_ATTR_POINTSATY, SP_ATTR_POINTSATZ, SP_ATTR_LIMITINGCONEANGLE, - /*feFlood*/ - SP_ATTR_FLOODCOLOR, - SP_ATTR_FLOODOPACITY, /* SPGaussianBlur */ SP_ATTR_STDDEVIATION, /*feImage*/ diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index d0c6d2d56..0d1b56d54 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -16,7 +16,7 @@ #include <2geom/transforms.h> #include #include -#include "style.h" +#include "sp-object.h" #include "svg/svg.h" #include "display/cairo-utils.h" #include "display/nr-svgfonts.h" -- cgit v1.2.3 From 093d8ae838d3913f57adfa624195b4e449852aae Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 22 Dec 2012 17:37:11 +0100 Subject: Bug fix for color-interpolation, color-interpolation-filters. Get rid of annoying warning. (bzr r11970) --- src/style.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/style.cpp b/src/style.cpp index 3e58a0404..650b08aea 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -677,9 +677,9 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr) } } /* color interpolation */ - SPS_READ_PENUM_IF_UNSET(&style->color_interpolation, repr, "color_interpolation", enum_color_interpolation, true); + SPS_READ_PENUM_IF_UNSET(&style->color_interpolation, repr, "color-interpolation", enum_color_interpolation, true); /* color interpolation filters*/ - SPS_READ_PENUM_IF_UNSET(&style->color_interpolation_filters, repr, "color_interpolation_filters", enum_color_interpolation, true); + SPS_READ_PENUM_IF_UNSET(&style->color_interpolation_filters, repr, "color-interpolation-filters", enum_color_interpolation, true); /* fill */ if (!style->fill.set) { val = repr->attribute("fill"); @@ -1234,11 +1234,7 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) } break; case SP_PROP_COLOR_INTERPOLATION_FILTERS: - // We read it but issue warning SPS_READ_IENUM_IF_UNSET(&style->color_interpolation_filters, val, enum_color_interpolation, true); - if( style->color_interpolation_filters.value != SP_CSS_COLOR_INTERPOLATION_SRGB ) { - g_warning("Inkscape currently only supports color-interpolation-filters = sRGB"); - } break; case SP_PROP_COLOR_PROFILE: g_warning("Unimplemented style property SP_PROP_COLOR_PROFILE: value: %s", val); -- cgit v1.2.3 From 7215dbf9d7ba8c147c66f16f23c0d6481491c76b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 22 Dec 2012 17:40:01 +0100 Subject: Add utilities to tag a cairo surface with color interpolation value. (bzr r11971) --- src/display/cairo-utils.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++++ src/display/cairo-utils.h | 14 ++++++ 2 files changed, 124 insertions(+) (limited to 'src') diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 2e2eb42dd..92303fed8 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -24,6 +24,7 @@ #include <2geom/transforms.h> #include <2geom/sbasis-to-bezier.h> #include "color.h" +#include "style.h" #include "helper/geom-curves.h" namespace Inkscape { @@ -276,6 +277,26 @@ feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv) } } +SPColorInterpolation +get_cairo_surface_ci(cairo_surface_t *surface) { + void* data = cairo_surface_get_user_data( surface, &ci_key ); + if( data != NULL ) { + return (SPColorInterpolation)GPOINTER_TO_INT( data ); + } else { + return SP_CSS_COLOR_INTERPOLATION_AUTO; + } +} + +void +set_cairo_surface_ci(cairo_surface_t *surface, SPColorInterpolation ci) { + cairo_surface_set_user_data(surface, &ci_key, GINT_TO_POINTER (ci), NULL); +} + +void +copy_cairo_surface_ci(cairo_surface_t *in, cairo_surface_t *out) { + cairo_surface_set_user_data(out, &ci_key, cairo_surface_get_user_data(in, &ci_key), NULL); +} + void ink_cairo_set_source_rgba32(cairo_t *ct, guint32 rgba) { @@ -395,6 +416,7 @@ cairo_surface_t * ink_cairo_surface_create_identical(cairo_surface_t *s) { cairo_surface_t *ns = ink_cairo_surface_create_same_size(s, cairo_surface_get_content(s)); + cairo_surface_set_user_data(ns, &ci_key, cairo_surface_get_user_data(s, &ci_key), NULL); return ns; } @@ -547,6 +569,94 @@ void ink_cairo_surface_average_color_premul(cairo_surface_t *surface, double &r, a = CLAMP(a, 0.0, 1.0); } +void srgb_to_linear( guint32* c, guint32 a ) { + + *c = unpremul_alpha( *c, a ); + + double cc = *c/255.0; + + if( cc < 0.04045 ) { + cc /= 12.92; + } else { + cc = pow( (cc+0.055)/1.055, 2.4 ); + } + cc *= 255.0; + + *c = (int)cc; + + *c = premul_alpha( *c, a ); +} + +void linear_to_srgb( guint32* c, guint32 a ) { + + *c = unpremul_alpha( *c, a ); + + double cc = *c/255.0; + + if( cc < 0.0031308 ) { + cc *= 12.92; + } else { + cc = pow( cc, 1.0/2.4 )*1.055-0.055; + } + cc *= 255.0; + + *c = (int)cc; + + *c = premul_alpha( *c, a ); +} + +int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) +{ + cairo_surface_flush(surface); + int width = cairo_image_surface_get_width(surface); + int height = cairo_image_surface_get_height(surface); + int stride = cairo_image_surface_get_stride(surface); + unsigned char *data = cairo_image_surface_get_data(surface); + + /* TODO convert this to OpenMP somehow */ + for (int y = 0; y < height; ++y, data += stride) { + for (int x = 0; x < width; ++x) { + guint32 px = *reinterpret_cast(data + 4*x); + EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting + if( a != 0 ) { + srgb_to_linear( &r, a ); + srgb_to_linear( &g, a ); + srgb_to_linear( &b, a ); + } + ASSEMBLE_ARGB32(px2, a,r,g,b); + *reinterpret_cast(data + 4*x) = px2; + } + } + set_cairo_surface_ci( surface, SP_CSS_COLOR_INTERPOLATION_LINEARRGB ); + return width * height; +} + +int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) +{ + cairo_surface_flush(surface); + int width = cairo_image_surface_get_width(surface); + int height = cairo_image_surface_get_height(surface); + int stride = cairo_image_surface_get_stride(surface); + unsigned char *data = cairo_image_surface_get_data(surface); + + /* TODO convert this to OpenMP somehow */ + for (int y = 0; y < height; ++y, data += stride) { + for (int x = 0; x < width; ++x) { + guint32 px = *reinterpret_cast(data + 4*x); + EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting + if( a != 0 ) { + linear_to_srgb( &r, a ); + linear_to_srgb( &g, a ); + linear_to_srgb( &b, a ); + } + ASSEMBLE_ARGB32(px2, a,r,g,b); + *reinterpret_cast(data + 4*x) = px2; + } + } + set_cairo_surface_ci( surface, SP_CSS_COLOR_INTERPOLATION_SRGB ); + return width * height; +} + cairo_pattern_t * ink_cairo_pattern_create_checkerboard() { diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index e67872891..edaf5ebaa 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -15,6 +15,7 @@ #include #include #include <2geom/forward.h> +#include "style.h" struct SPColor; struct _GdkPixbuf; @@ -81,6 +82,16 @@ public: } // namespace Inkscape +/** + * Key for cairo_surface_t to keep track of current color interpolation value + * Only the address of the structure is used, it is never initialized. See: + * http://www.cairographics.org/manual/cairo-Types.html#cairo-user-data-key-t + */ +static cairo_user_data_key_t ci_key; +SPColorInterpolation get_cairo_surface_ci(cairo_surface_t *surface); +void set_cairo_surface_ci(cairo_surface_t *surface, SPColorInterpolation cif); +void copy_cairo_surface_ci(cairo_surface_t *in, cairo_surface_t *out); + void ink_cairo_set_source_color(cairo_t *ct, SPColor const &color, double opacity); void ink_cairo_set_source_rgba32(cairo_t *ct, guint32 rgba); void ink_cairo_transform(cairo_t *ct, Geom::Affine const &m); @@ -102,6 +113,9 @@ guint32 ink_cairo_surface_average_color(cairo_surface_t *surface); void ink_cairo_surface_average_color(cairo_surface_t *surface, double &r, double &g, double &b, double &a); void ink_cairo_surface_average_color_premul(cairo_surface_t *surface, double &r, double &g, double &b, double &a); +int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface); +int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface); + cairo_pattern_t *ink_cairo_pattern_create_checkerboard(); void convert_pixels_pixbuf_to_argb32(guchar *data, int w, int h, int rs); -- cgit v1.2.3 From 8c4d3b68e4a5727b2205ec136d6fb5f50289d1e9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 22 Dec 2012 17:43:07 +0100 Subject: Add support for color-interpolation-filters = linearRGB. (bzr r11972) --- src/display/nr-filter-blend.cpp | 44 ++++++++++++++++++++++++++-- src/display/nr-filter-colormatrix.cpp | 29 ++++++++++++++++++ src/display/nr-filter-component-transfer.cpp | 27 +++++++++++++++++ src/display/nr-filter-composite.cpp | 41 ++++++++++++++++++++++++++ src/display/nr-filter-convolve-matrix.cpp | 29 ++++++++++++++++-- src/display/nr-filter-diffuselighting.cpp | 12 ++++++++ src/display/nr-filter-displacement-map.cpp | 28 ++++++++++++++++++ src/display/nr-filter-flood.cpp | 9 ++++++ src/display/nr-filter-gaussian.cpp | 34 +++++++++++++++++++++ src/display/nr-filter-image.cpp | 10 +++++++ src/display/nr-filter-merge.cpp | 19 ++++++++++++ src/display/nr-filter-morphology.cpp | 6 ++++ src/display/nr-filter-offset.cpp | 6 ++++ src/display/nr-filter-primitive.cpp | 14 ++++++++- src/display/nr-filter-primitive.h | 9 ++++++ src/display/nr-filter-slot.cpp | 10 +++++++ src/display/nr-filter-specularlighting.cpp | 12 ++++++++ src/display/nr-filter-turbulence.cpp | 7 +++++ src/display/nr-filter.cpp | 11 +++++++ src/filter-chemistry.cpp | 5 +++- src/sp-filter-primitive.cpp | 15 +++++++--- src/sp-filter.cpp | 28 ++++-------------- 22 files changed, 372 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp index 267883b4b..2ada36949 100644 --- a/src/display/nr-filter-blend.cpp +++ b/src/display/nr-filter-blend.cpp @@ -146,13 +146,53 @@ void FilterBlend::render_cairo(FilterSlot &slot) cairo_surface_t *input1 = slot.getcairo(_input); cairo_surface_t *input2 = slot.getcairo(_input2); - cairo_content_t ct1 = cairo_surface_get_content(input1); - cairo_content_t ct2 = cairo_surface_get_content(input2); + // We may need to transform input surface to correct color interpolation space. The input surface + // might be used as input to another primitive but it is likely that all the primitives in a given + // filter use the same color interpolation space so we don't copy the input before converting. + // The converting function tags surface with the proper ci value. + // Note: an alpha only surface should not have ci set. + SPColorInterpolation ci_in1 = get_cairo_surface_ci(input1); + SPColorInterpolation ci_in2 = get_cairo_surface_ci(input2); + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + } + if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterColorBlend: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( input1 ); + } + if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterColorBlend: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( input1 ); + } + if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterColorBlend: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( input2 ); + } + if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterColorBlend: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( input2 ); + } // input2 is the "background" image // out should be ARGB32 if any of the inputs is ARGB32 cairo_surface_t *out = ink_cairo_surface_create_output(input1, input2); + if( cairo_surface_get_content( out ) == CAIRO_CONTENT_COLOR_ALPHA ) { + set_cairo_surface_ci(out, ci_fp ); + } + + // std::cout << "FilterBlend: ci data: " + // << " in1: " << get_cairo_surface_ci(input1) + // << " in2: " << get_cairo_surface_ci(input2) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; + cairo_content_t ct1 = cairo_surface_get_content(input1); + cairo_content_t ct2 = cairo_surface_get_content(input2); if ((ct1 == CAIRO_CONTENT_ALPHA && ct2 == CAIRO_CONTENT_ALPHA) || _blend_mode == BLEND_NORMAL) { diff --git a/src/display/nr-filter-colormatrix.cpp b/src/display/nr-filter-colormatrix.cpp index fad6215ff..5d3cf6a9e 100644 --- a/src/display/nr-filter-colormatrix.cpp +++ b/src/display/nr-filter-colormatrix.cpp @@ -152,12 +152,41 @@ void FilterColorMatrix::render_cairo(FilterSlot &slot) { cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = NULL; + + // We may need to transform input surface to correct color interpolation space. The input surface + // might be used as input to another primitive but it is likely that all the primitives in a given + // filter use the same color interpolation space so we don't copy the input before converting. + // The converting function tags surface with the proper ci value. + // Note: an alpha only surface should not have ci set. + SPColorInterpolation ci_in = get_cairo_surface_ci(input); + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterColorMatrix: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( input ); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterColorMatrix: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( input ); + } + if (type == COLORMATRIX_LUMINANCETOALPHA) { out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_ALPHA); } else { out = ink_cairo_surface_create_identical(input); + // Set ci to that used for computation + set_cairo_surface_ci(out, ci_fp); } + // std::cout << "FilterColorMatrix: ci data: " + // << " in1: " << get_cairo_surface_ci(input) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; + switch (type) { case COLORMATRIX_MATRIX: ink_cairo_surface_filter(input, out, FilterColorMatrix::ColorMatrixMatrix(values)); diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index 226a73cef..8efcc9c4d 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -238,6 +238,33 @@ void FilterComponentTransfer::render_cairo(FilterSlot &slot) { cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA); + + // We may need to transform input surface to correct color interpolation space. The input surface + // might be used as input to another primitive but it is likely that all the primitives in a given + // filter use the same color interpolation space so we don't copy the input before converting. + // The converting function tags surface with the proper ci value. + SPColorInterpolation ci_in = get_cairo_surface_ci(input); + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + set_cairo_surface_ci(out, ci_fp ); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterComponentTransfer: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( input ); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterComponentTransfer: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( input ); + } + + // std::cout << "FilterComponentTransfer: ci data: " + // << " in1: " << get_cairo_surface_ci(input) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; + //cairo_surface_t *outtemp = ink_cairo_surface_create_identical(out); ink_cairo_surface_blit(input, out); diff --git a/src/display/nr-filter-composite.cpp b/src/display/nr-filter-composite.cpp index 040424cb3..f5ec94a46 100644 --- a/src/display/nr-filter-composite.cpp +++ b/src/display/nr-filter-composite.cpp @@ -66,7 +66,48 @@ void FilterComposite::render_cairo(FilterSlot &slot) cairo_surface_t *input1 = slot.getcairo(_input); cairo_surface_t *input2 = slot.getcairo(_input2); + // We may need to transform input surface to correct color interpolation space. The input surface + // might be used as input to another primitive but it is likely that all the primitives in a given + // filter use the same color interpolation space so we don't copy the input before converting. + // The converting function tags surface with the proper ci value. + // Note: an alpha only surface should not have ci set. + SPColorInterpolation ci_in1 = get_cairo_surface_ci(input1); + SPColorInterpolation ci_in2 = get_cairo_surface_ci(input2); + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + } + if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterColorComposite: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( input1 ); + } + if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterColorComposite: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( input1 ); + } + if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + std::cout << "FilterColorComposite: srgb -> linear" << std::endl; + //ink_cairo_surface_srgb_to_linear( input2 ); + } + if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterColorComposite: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( input2 ); + } + cairo_surface_t *out = ink_cairo_surface_create_output(input1, input2); + if( cairo_surface_get_content( out ) == CAIRO_CONTENT_COLOR_ALPHA ) { + set_cairo_surface_ci(out, ci_fp ); + } + + // std::cout << "FilterComposite: ci data: " + // << " in1: " << get_cairo_surface_ci(input1) + // << " in2: " << get_cairo_surface_ci(input2) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; if (op == COMPOSITE_ARITHMETIC) { ink_cairo_surface_blend(input1, input2, out, ComposeArithmetic(k1, k2, k3, k4)); diff --git a/src/display/nr-filter-convolve-matrix.cpp b/src/display/nr-filter-convolve-matrix.cpp index 5469aff88..6ee67d126 100644 --- a/src/display/nr-filter-convolve-matrix.cpp +++ b/src/display/nr-filter-convolve-matrix.cpp @@ -104,8 +104,6 @@ void FilterConvolveMatrix::render_cairo(FilterSlot &slot) static bool bias_warning = false; static bool edge_warning = false; - cairo_surface_t *input = slot.getcairo(_input); - if (orderX<=0 || orderY<=0) { g_warning("Empty kernel!"); return; @@ -119,8 +117,35 @@ void FilterConvolveMatrix::render_cairo(FilterSlot &slot) return; } + cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_identical(input); + // We may need to transform input surface to correct color interpolation space. The input surface + // might be used as input to another primitive but it is likely that all the primitives in a given + // filter use the same color interpolation space so we don't copy the input before converting. + // The converting function tags surface with the proper ci value. + SPColorInterpolation ci_in = get_cairo_surface_ci(input); + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + set_cairo_surface_ci(out, ci_fp); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterConvolveMatrix: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( input ); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterConvolveMatrix: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( input ); + } + + // std::cout << "FilterConvolveMatrix: ci data: " + // << " in1: " << get_cairo_surface_ci(input) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; + if (bias!=0 && !bias_warning) { g_warning("It is unknown whether Inkscape's implementation of bias in feConvolveMatrix " "is correct!"); diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp index fcc986189..bd473eb76 100644 --- a/src/display/nr-filter-diffuselighting.cpp +++ b/src/display/nr-filter-diffuselighting.cpp @@ -126,6 +126,18 @@ void FilterDiffuseLighting::render_cairo(FilterSlot &slot) cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA); + // Only alpha channel of input is used, no need to check input color_interpolation_filter value. + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); + set_cairo_surface_ci(out, ci_fp ); + } + + // std::cout << "FilterDiffuseLighting: ci data: " + // << " in1: " << get_cairo_surface_ci(input) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; + Geom::Rect slot_area = slot.get_slot_area(); Geom::Point p = slot_area.min(); Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); diff --git a/src/display/nr-filter-displacement-map.cpp b/src/display/nr-filter-displacement-map.cpp index 9b44c2302..909e11f50 100644 --- a/src/display/nr-filter-displacement-map.cpp +++ b/src/display/nr-filter-displacement-map.cpp @@ -74,6 +74,34 @@ void FilterDisplacementMap::render_cairo(FilterSlot &slot) cairo_surface_t *texture = slot.getcairo(_input); cairo_surface_t *map = slot.getcairo(_input2); cairo_surface_t *out = ink_cairo_surface_create_identical(texture); + // color_interpolation_filters for out same as texture. See spec. + copy_cairo_surface_ci( texture, out ); + + // We may need to transform map surface to correct color interpolation space. The map surface + // might be used as input to another primitive but it is likely that all the primitives in a given + // filter use the same color interpolation space so we don't copy the map before converting. + // The converting function tags surface with the proper ci value. + SPColorInterpolation ci_map = get_cairo_surface_ci(map); + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + } + if( ci_map == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterDisplacementMap: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( map ); + } + if( ci_map == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterDisplacementMap: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( map ); + } + + // std::cout << "FilterDisplacementMap: ci data: " + // << " texture: " << get_cairo_surface_ci(texture) + // << " map: " << get_cairo_surface_ci(map) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); double scalex = scale * trans.expansionX(); diff --git a/src/display/nr-filter-flood.cpp b/src/display/nr-filter-flood.cpp index 56a27ecd7..649d4609f 100644 --- a/src/display/nr-filter-flood.cpp +++ b/src/display/nr-filter-flood.cpp @@ -45,6 +45,8 @@ void FilterFlood::render_cairo(FilterSlot &slot) #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + // DOES THIS REALLY BELONG HERE? SHOULDN'T ICC BE APPLIED AFTER ALL COMPOSITING? + // What if color_interpolation_filter is set to linear RGB? if (icc) { guchar ru, gu, bu; icc_color_to_sRGB(icc, &ru, &gu, &bu); @@ -55,6 +57,13 @@ void FilterFlood::render_cairo(FilterSlot &slot) #endif cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA); + // color_interpolation_filter is determined by CSS value (see spec. Turbulence). + if( _style ) { + set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); + } + + // std::cout << "FilterFlood: ci data: out: " + // << get_cairo_surface_ci(out) << std::endl; // Get filter primitive area in user units Geom::Rect fp = filter_primitive_area( slot.get_units() ); diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index 6ef321992..3b29e825d 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -553,6 +553,30 @@ void FilterGaussian::render_cairo(FilterSlot &slot) cairo_surface_t *in = slot.getcairo(_input); if (!in) return; + // We may need to transform input surface to correct color interpolation space. The input surface + // might be used as input to another primitive but it is likely that all the primitives in a given + // filter use the same color interpolation space so we don't copy the input before converting. + // The converting function tags surface with the proper ci value. + // Note: an alpha only surface should not have ci set. + SPColorInterpolation ci_in = get_cairo_surface_ci(in); + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterGaussian: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( in ); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterGaussian: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( in ); + } + + // std::cout << "FilterGaussian: ci data: in: " + // << get_cairo_surface_ci( in ) << std::endl; + // zero deviation = no change in output if (_deviation_x <= 0 && _deviation_y <= 0) { cairo_surface_t *cp = ink_cairo_surface_copy(in); @@ -660,10 +684,20 @@ void FilterGaussian::render_cairo(FilterSlot &slot) cairo_paint(ct); cairo_destroy(ct); + if( cairo_surface_get_content( upsampled ) == CAIRO_CONTENT_COLOR_ALPHA ) { + set_cairo_surface_ci( upsampled, ci_fp ); + } + // std::cout << "FilterGaussian: ci data: resampled: " + // << get_cairo_surface_ci(upsampled) << std::endl; slot.set(_output, upsampled); cairo_surface_destroy(upsampled); cairo_surface_destroy(downsampled); } else { + if( cairo_surface_get_content( downsampled ) == CAIRO_CONTENT_COLOR_ALPHA ) { + set_cairo_surface_ci( downsampled, ci_fp ); + } + // std::cout << "FilterGaussian: ci data: downsampled: " + // << get_cairo_surface_ci(downsampled) << std::endl; slot.set(_output, downsampled); cairo_surface_destroy(downsampled); } diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index bc18cbcc6..8aae29cbe 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -120,6 +120,11 @@ void FilterImage::render_cairo(FilterSlot &slot) drawing.render(ct, render_rect); SVGElem->invoke_hide(key); + // For the moment, we'll assume that any image is in sRGB color space + set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB); + // std::cout << "FilterImage: ci set to: " + // << get_cairo_surface_ci(out) << std::endl; + slot.set(_output, out); cairo_surface_destroy(out); return; @@ -185,6 +190,11 @@ void FilterImage::render_cairo(FilterSlot &slot) cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, sa.width(), sa.height()); + // For the moment, we'll assume that any image is in sRGB color space + set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB); + // std::cout << "FilterImage: ci set to: " + // << get_cairo_surface_ci(out) << std::endl; + cairo_t *ct = cairo_create(out); cairo_translate(ct, -sa.min()[Geom::X], -sa.min()[Geom::Y]); diff --git a/src/display/nr-filter-merge.cpp b/src/display/nr-filter-merge.cpp index 759d7d6d1..4d3862a33 100644 --- a/src/display/nr-filter-merge.cpp +++ b/src/display/nr-filter-merge.cpp @@ -33,6 +33,11 @@ void FilterMerge::render_cairo(FilterSlot &slot) { if (_input_image.empty()) return; + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; + } + // output is RGBA if at least one input is RGBA bool rgba32 = false; cairo_surface_t *out = NULL; @@ -40,6 +45,7 @@ void FilterMerge::render_cairo(FilterSlot &slot) cairo_surface_t *in = slot.getcairo(*i); if (cairo_surface_get_content(in) == CAIRO_CONTENT_COLOR_ALPHA) { out = ink_cairo_surface_create_identical(in); + set_cairo_surface_ci( out, ci_fp ); rgba32 = true; break; } @@ -52,6 +58,19 @@ void FilterMerge::render_cairo(FilterSlot &slot) for (std::vector::iterator i = _input_image.begin(); i != _input_image.end(); ++i) { cairo_surface_t *in = slot.getcairo(*i); + + SPColorInterpolation ci_in = get_cairo_surface_ci(in); + //std::cout << "FilterMerge: slot: ci: " << ci_in << std::endl; + if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "FilterMerge: srgb -> linear" << std::endl; + ink_cairo_surface_srgb_to_linear( in ); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + //std::cout << "FilterMerge: linear -> srgb" << std::endl; + ink_cairo_surface_linear_to_srgb( in ); + } cairo_set_source_surface(out_ct, in, 0, 0); cairo_paint(out_ct); } diff --git a/src/display/nr-filter-morphology.cpp b/src/display/nr-filter-morphology.cpp index 18f99cdcd..7447b76fe 100644 --- a/src/display/nr-filter-morphology.cpp +++ b/src/display/nr-filter-morphology.cpp @@ -164,6 +164,7 @@ void FilterMorphology::render_cairo(FilterSlot &slot) if (xradius == 0.0 || yradius == 0.0) { // output is transparent black cairo_surface_t *out = ink_cairo_surface_create_identical(input); + copy_cairo_surface_ci(input, out); slot.set(_output, out); cairo_surface_destroy(out); return; @@ -192,6 +193,11 @@ void FilterMorphology::render_cairo(FilterSlot &slot) cairo_surface_t *out = ink_cairo_surface_create_identical(interm); + // color_interpolation_filters for out same as input. See spec (DisplacementMap). + copy_cairo_surface_ci(input, out); + // std::cout << "FilterMorphology: ci set to: " + // << get_cairo_surface_ci(out) << std::endl; + if (Operator == MORPHOLOGY_OPERATOR_DILATE) { if (bpp == 1) { morphologicalFilter1D< std::greater, Geom::Y, 1 >(interm, out, yr); diff --git a/src/display/nr-filter-offset.cpp b/src/display/nr-filter-offset.cpp index 833f6ecc9..3543de6df 100644 --- a/src/display/nr-filter-offset.cpp +++ b/src/display/nr-filter-offset.cpp @@ -35,6 +35,12 @@ void FilterOffset::render_cairo(FilterSlot &slot) { cairo_surface_t *in = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_identical(in); + // color_interpolation_filters for out same as in. See spec (DisplacementMap). + copy_cairo_surface_ci(in, out); + + // std::cout << "FilterOffset: ci data: out: " + // << get_cairo_surface_ci(out) << std::endl; + cairo_t *ct = cairo_create(out); Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index ce562668a..fca82c810 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -20,6 +20,7 @@ #include "desktop-handles.h" #include "document.h" #include "sp-root.h" +#include "style.h" namespace Inkscape { namespace Filters { @@ -45,11 +46,14 @@ FilterPrimitive::FilterPrimitive() _subregion_y.unset(SVGLength::PERCENT, 0, 0); _subregion_width.unset(SVGLength::PERCENT, 1, 0); _subregion_height.unset(SVGLength::PERCENT, 1, 0); + + _style = NULL; } FilterPrimitive::~FilterPrimitive() { - // Nothing to do here + if(_style) + sp_style_unref(_style); } void FilterPrimitive::render_cairo(FilterSlot &slot) @@ -179,6 +183,14 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units) return area; } +void FilterPrimitive::setStyle(SPStyle *style) +{ + if (style) sp_style_ref(style); + if (_style) sp_style_unref(_style); + _style = style; +} + + } /* namespace Filters */ } /* namespace Inkscape */ diff --git a/src/display/nr-filter-primitive.h b/src/display/nr-filter-primitive.h index da2097156..214b2cfc5 100644 --- a/src/display/nr-filter-primitive.h +++ b/src/display/nr-filter-primitive.h @@ -16,6 +16,8 @@ #include "display/nr-filter-types.h" #include "svg/svg-length.h" +class SPStyle; + namespace Inkscape { namespace Filters { @@ -113,6 +115,11 @@ public: */ virtual bool can_handle_affine(Geom::Affine const &) { return false; } + /** + * Sets style for access to properties used by filter primitives. + */ + void setStyle(SPStyle *style); + protected: int _input; int _output; @@ -122,6 +129,8 @@ protected: SVGLength _subregion_y; SVGLength _subregion_width; SVGLength _subregion_height; + + SPStyle *_style; }; diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp index 4f7a8849e..64c5143ff 100644 --- a/src/display/nr-filter-slot.cpp +++ b/src/display/nr-filter-slot.cpp @@ -84,11 +84,13 @@ cairo_surface_t *FilterSlot::getcairo(int slot_nr) case NR_FILTER_SOURCEGRAPHIC: { cairo_surface_t *tr = _get_transformed_source_graphic(); _set_internal(NR_FILTER_SOURCEGRAPHIC, tr); + //std::cout << "Source Graphic: ci data: " << get_cairo_surface_ci( tr ) << std::endl; cairo_surface_destroy(tr); } break; case NR_FILTER_BACKGROUNDIMAGE: { cairo_surface_t *bg = _get_transformed_background(); _set_internal(NR_FILTER_BACKGROUNDIMAGE, bg); + //std::cout << "Background Image: ci data: " << get_cairo_surface_ci( bg ) << std::endl; cairo_surface_destroy(bg); } break; case NR_FILTER_SOURCEALPHA: { @@ -129,6 +131,9 @@ cairo_surface_t *FilterSlot::_get_transformed_source_graphic() if (trans.isTranslation()) { cairo_surface_reference(_source_graphic); + + // Assume all source graphics are sRGB + set_cairo_surface_ci( _source_graphic, SP_CSS_COLOR_INTERPOLATION_SRGB ); return _source_graphic; } @@ -145,6 +150,8 @@ cairo_surface_t *FilterSlot::_get_transformed_source_graphic() cairo_paint(tsg_ct); cairo_destroy(tsg_ct); + // Assume all source graphics are sRGB + set_cairo_surface_ci( tsg, SP_CSS_COLOR_INTERPOLATION_SRGB ); return tsg; } @@ -172,6 +179,9 @@ cairo_surface_t *FilterSlot::_get_transformed_background() tbg = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, _slot_w, _slot_h); } + // Assume all source graphics are sRGB + set_cairo_surface_ci( tbg, SP_CSS_COLOR_INTERPOLATION_SRGB ); + return tbg; } diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp index 0242754eb..4cf8f319d 100644 --- a/src/display/nr-filter-specularlighting.cpp +++ b/src/display/nr-filter-specularlighting.cpp @@ -139,6 +139,18 @@ void FilterSpecularLighting::render_cairo(FilterSlot &slot) cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA); + // Only alpha channel of input is used, no need to check input color_interpolation_filter value. + SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; + if( _style ) { + set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); + set_cairo_surface_ci(out, ci_fp ); + } + + // std::cout << "FilterSpecularLighting: ci data: " + // << " in1: " << get_cairo_surface_ci(input) + // << " out: " << get_cairo_surface_ci(out) + // << std::endl; + Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); Geom::Point p = slot.get_slot_area().min(); double x0 = p[Geom::X]; diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index bce532f21..e2b52a1d4 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -375,6 +375,13 @@ void FilterTurbulence::render_cairo(FilterSlot &slot) cairo_surface_t *input = slot.getcairo(_input); cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA); + // color_interpolation_filter is determined by CSS value (see spec. Turbulence). + if( _style ) { + set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); + } + // std::cout << "FilterTurbulance: ci data: out: " + // << get_cairo_surface_ci(out) << std::endl; + if (!gen->ready()) { Geom::Point ta(fTileX, fTileY); Geom::Point tb(fTileX + fTileWidth, fTileY + fTileHeight); diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index f580a5044..a29ac551a 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -38,6 +38,7 @@ #include "display/nr-filter-tile.h" #include "display/nr-filter-turbulence.h" +#include "display/cairo-utils.h" #include "display/drawing.h" #include "display/drawing-item.h" #include "display/drawing-context.h" @@ -159,6 +160,16 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D Geom::Point origin = graphic.targetLogicalBounds().min(); cairo_surface_t *result = slot.get_result(_output_slot); + + // std::cout << "Filter: result: ci data: " + // << get_cairo_surface_ci(result) << std::endl; + + // Assume for the moment that we paint the filter in sRGB + if( get_cairo_surface_ci(result) == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + //std::cout << "Filter: result: linear -> sRGB" << std::endl; + ink_cairo_surface_linear_to_srgb( result ); + } + graphic.setSource(result, origin[Geom::X], origin[Geom::Y]); graphic.setOperator(CAIRO_OPERATOR_SOURCE); graphic.paint(); diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index fc74ee8a2..14bd00057 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -98,7 +98,10 @@ SPFilter *new_filter(SPDocument *document) Inkscape::XML::Node *repr; repr = xml_doc->createElement("svg:filter"); - // Inkscape only supports sRGB. See note in sp-filter.cpp. + // Inkscape now supports both sRGB and linear color-interpolation-filters. + // But, for the moment, keep sRGB as default value for new filters + // (historically set to sRGB and doesn't require conversion between + // filter cairo surfaces and other types of cairo surfaces). SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property(css, "color-interpolation-filters", "sRGB"); sp_repr_css_change(repr, css, "style"); diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index b63a05b4b..7ddf3b065 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -20,6 +20,7 @@ #include #include "attributes.h" +#include "style.h" #include "sp-filter-primitive.h" #include "xml/repr.h" #include "sp-filter.h" @@ -100,16 +101,17 @@ static void sp_filter_primitive_init(SPFilterPrimitive *filter_primitive) static void sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { - if ((static_cast(filter_primitive_parent_class))->build) { - (static_cast(filter_primitive_parent_class))->build(object, document, repr); - } - + object->readAttr( "style" ); // struct not derived from SPItem, we need to do this ourselves. object->readAttr( "in" ); object->readAttr( "result" ); object->readAttr( "x" ); object->readAttr( "y" ); object->readAttr( "width" ); object->readAttr( "height" ); + + if ((static_cast(filter_primitive_parent_class))->build) { + (static_cast(filter_primitive_parent_class))->build(object, document, repr); + } } /** @@ -188,7 +190,9 @@ sp_filter_primitive_update(SPObject *object, SPCtx *ctx, guint flags) { //SPFilterPrimitive *filter_primitive = SP_FILTER_PRIMITIVE(object); + // Is this required? if (flags & SP_OBJECT_MODIFIED_FLAG) { + object->readAttr( "style" ); object->readAttr( "in" ); object->readAttr( "result" ); object->readAttr( "x" ); @@ -311,6 +315,9 @@ void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, Inkscape::F /* TODO: place here code to handle input images, filter area etc. */ nr_prim->set_subregion( sp_prim->x, sp_prim->y, sp_prim->width, sp_prim->height ); + + // Give renderer access to filter properties + nr_prim->setStyle( sp_prim->style ); } diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index a20856f53..c7dce3850 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -130,11 +130,8 @@ sp_filter_init(SPFilter *filter) static void sp_filter_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { - if (((SPObjectClass *) filter_parent_class)->build) { - ((SPObjectClass *) filter_parent_class)->build(object, document, repr); - } - //Read values of key attributes from XML nodes into object. + object->readAttr( "style" ); // struct not derived from SPItem, we need to do this ourselves. object->readAttr( "filterUnits" ); object->readAttr( "primitiveUnits" ); object->readAttr( "x" ); @@ -144,6 +141,10 @@ sp_filter_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *rep object->readAttr( "filterRes" ); object->readAttr( "xlink:href" ); + if (((SPObjectClass *) filter_parent_class)->build) { + ((SPObjectClass *) filter_parent_class)->build(object, document, repr); + } + //is this necessary? document->addResource("filter", object); } @@ -366,25 +367,6 @@ sp_filter_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::N g_free(uri_string); } - // TODO: This is evil, correctly implement support for color-interpolation-filters!!! - // The color-interpolation-filters attribute is initially set to linearRGB according to the SVG standard. - // However, Inkscape completely ignores it and implicitly assumes that it is sRGB (like color-interpolation). - // This results in a discrepancy between Inkscape and other renderers in how they render filters. - // To mitigate this problem I've (Jasper van de Gronde,th.v.d.gronde@hccnet.nl) added this to ensure that at least - // any filters written by Inkscape will henceforth be rendered the same in other renderers. - // In the future Inkscape should have proper support for the color-interpolation properties and this should be changed. - - // repr->setAttribute("color-interpolation-filters", "sRGB"); - - // Actually, the above line is not correct as the attribute is only allowed on filter - // primitives and not objects. However, it is allowed as a property in a style - // attribute. Note, this property must also be set in sp-filter-chemistry, filter_new() as the - // code here is not necessarily called when a new filter is created. 29 Aug 2011 Tav. - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, "color-interpolation-filters", "sRGB"); - sp_repr_css_change(repr, css, "style"); - sp_repr_css_attr_unref(css); - if (((SPObjectClass *) filter_parent_class)->write) { ((SPObjectClass *) filter_parent_class)->write(object, doc, repr, flags); } -- cgit v1.2.3 From c6161437ec7b3f36069fe6e16bd250b2a59fbcf5 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 22 Dec 2012 17:27:04 +0000 Subject: ruler (Merge from GIMP): Convert to no-window widget and provide separate accessors for position (bzr r11973) --- src/widgets/desktop-widget.cpp | 16 +- src/widgets/ruler.cpp | 371 ++++++++++++++++++++++++----------------- src/widgets/ruler.h | 30 ++-- 3 files changed, 236 insertions(+), 181 deletions(-) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 0fd8fd010..b94a70417 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1717,12 +1717,8 @@ void SPDesktopWidget::viewSetPosition (Geom::Point p) { Geom::Point const origin = ( p - ruler_origin ); - gdouble hlower, hupper, hmax_range; - gdouble vlower, vupper, vmax_range; - sp_ruler_get_range(SP_RULER(hruler), &hlower, &hupper, NULL, &hmax_range); - sp_ruler_set_range(SP_RULER(hruler), hlower, hupper, origin[Geom::X], hmax_range); - sp_ruler_get_range(SP_RULER(vruler), &vlower, &vupper, NULL, &vmax_range); - sp_ruler_set_range(SP_RULER(vruler), vlower, vupper, origin[Geom::Y], vmax_range); + sp_ruler_set_position(SP_RULER(hruler), origin[Geom::X]); + sp_ruler_set_position(SP_RULER(vruler), origin[Geom::Y]); } void @@ -1741,13 +1737,11 @@ sp_desktop_widget_update_hruler (SPDesktopWidget *dtw) * coincides with the pixel buffer, everything will line up nicely. */ Geom::IntRect viewbox = dtw->canvas->getViewboxIntegers(); - gdouble position; double const scale = dtw->desktop->current_zoom(); double s = viewbox.min()[Geom::X] / scale - dtw->ruler_origin[Geom::X]; double e = viewbox.max()[Geom::X] / scale - dtw->ruler_origin[Geom::X]; - sp_ruler_get_range(SP_RULER(dtw->hruler), NULL, NULL, &position, NULL); - sp_ruler_set_range(SP_RULER(dtw->hruler), s, e, position, (e - s)); + sp_ruler_set_range(SP_RULER(dtw->hruler), s, e, (e - s)); } void @@ -1759,13 +1753,11 @@ sp_desktop_widget_update_vruler (SPDesktopWidget *dtw) * coincides with the pixel buffer, everything will line up nicely. */ Geom::IntRect viewbox = dtw->canvas->getViewboxIntegers(); - gdouble position; double const scale = dtw->desktop->current_zoom(); double s = viewbox.min()[Geom::Y] / -scale - dtw->ruler_origin[Geom::Y]; double e = viewbox.max()[Geom::Y] / -scale - dtw->ruler_origin[Geom::Y]; - sp_ruler_get_range(SP_RULER(dtw->vruler), NULL, NULL, &position, NULL); - sp_ruler_set_range(SP_RULER(dtw->vruler), s, e, position, (e - s)); + sp_ruler_set_range(SP_RULER(dtw->vruler), s, e, (e - s)); } diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 54a64cb56..d5dcd4709 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -37,6 +37,7 @@ struct _SPRulerPrivate GtkOrientation orientation; SPRulerMetric *metric; + GdkWindow *input_window; cairo_surface_t *backing_store; gint slider_size; @@ -59,27 +60,29 @@ enum { PROP_METRIC }; -static void sp_ruler_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void sp_ruler_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void sp_ruler_realize (GtkWidget *widget); -static void sp_ruler_unrealize (GtkWidget *widget); -static void sp_ruler_size_request (GtkWidget *widget, - GtkRequisition *requisition); +static void sp_ruler_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void sp_ruler_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void sp_ruler_realize (GtkWidget *widget); +static void sp_ruler_unrealize (GtkWidget *widget); +static void sp_ruler_map (GtkWidget *widget); +static void sp_ruler_unmap (GtkWidget *widget); +static void sp_ruler_size_request (GtkWidget *widget, + GtkRequisition *requisition); #if GTK_CHECK_VERSION(3,0,0) -static void sp_ruler_get_preferred_width (GtkWidget *widget, - gint *minimal_width, - gint *natural_width); +static void sp_ruler_get_preferred_width (GtkWidget *widget, + gint *minimal_width, + gint *natural_width); -static void sp_ruler_get_preferred_height (GtkWidget *widget, - gint *minimal_height, - gint *natural_height); +static void sp_ruler_get_preferred_height (GtkWidget *widget, + gint *minimal_height, + gint *natural_height); #endif static void sp_ruler_size_allocate (GtkWidget *widget, @@ -92,9 +95,9 @@ static gboolean sp_ruler_draw (GtkWidget *widget, static gboolean sp_ruler_expose (GtkWidget *widget, GdkEventExpose *event); #endif -static void sp_ruler_make_pixmap (SPRuler *ruler); static void sp_ruler_draw_ticks (SPRuler *ruler); static void sp_ruler_draw_pos (SPRuler *ruler); +static void sp_ruler_make_pixmap (SPRuler *ruler); #define SP_RULER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SP_TYPE_RULER, SPRulerPrivate)) @@ -120,30 +123,34 @@ G_DEFINE_TYPE_WITH_CODE (SPRuler, sp_ruler, GTK_TYPE_WIDGET, static void sp_ruler_class_init (SPRulerClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - gobject_class->set_property = sp_ruler_set_property; - gobject_class->get_property = sp_ruler_get_property; + object_class->set_property = sp_ruler_set_property; + object_class->get_property = sp_ruler_get_property; - widget_class->realize = sp_ruler_realize; - widget_class->unrealize = sp_ruler_unrealize; + widget_class->realize = sp_ruler_realize; + widget_class->unrealize = sp_ruler_unrealize; + widget_class->map = sp_ruler_map; + widget_class->unmap = sp_ruler_unmap; + widget_class->size_allocate = sp_ruler_size_allocate; #if GTK_CHECK_VERSION(3,0,0) - widget_class->get_preferred_width = sp_ruler_get_preferred_width; + widget_class->get_preferred_width = sp_ruler_get_preferred_width; widget_class->get_preferred_height = sp_ruler_get_preferred_height; - widget_class->draw = sp_ruler_draw; + widget_class->draw = sp_ruler_draw; #else - widget_class->size_request = sp_ruler_size_request; - widget_class->expose_event = sp_ruler_expose; + widget_class->size_request = sp_ruler_size_request; + widget_class->expose_event = sp_ruler_expose; #endif - widget_class->size_allocate = sp_ruler_size_allocate; widget_class->motion_notify_event = sp_ruler_motion_notify; - g_object_class_override_property (gobject_class, + g_type_class_add_private (object_class, sizeof (SPRulerPrivate)); + + g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation"); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_LOWER, g_param_spec_double ("lower", _("Lower"), @@ -153,7 +160,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_UPPER, g_param_spec_double ("upper", _("Upper"), @@ -163,7 +170,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_POSITION, g_param_spec_double ("position", _("Position"), @@ -173,7 +180,7 @@ sp_ruler_class_init (SPRulerClass *klass) 0.0, static_cast(GTK_PARAM_READWRITE))); - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_MAX_SIZE, g_param_spec_double ("max-size", _("Max Size"), @@ -189,7 +196,7 @@ sp_ruler_class_init (SPRulerClass *klass) * * TODO: This should probably use g_param_spec_enum */ - g_object_class_install_property (gobject_class, + g_object_class_install_property (object_class, PROP_METRIC, g_param_spec_uint("metric", _("Metric"), @@ -197,34 +204,28 @@ sp_ruler_class_init (SPRulerClass *klass) 0, 8, SP_PX, static_cast(GTK_PARAM_READWRITE))); - - g_type_class_add_private (gobject_class, sizeof (SPRulerPrivate)); } static void sp_ruler_init (SPRuler *ruler) { - ruler->priv = G_TYPE_INSTANCE_GET_PRIVATE(ruler, - SP_TYPE_RULER, - SPRulerPrivate); - - SPRulerPrivate *priv = ruler->priv; - - priv->orientation = GTK_ORIENTATION_HORIZONTAL; - + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + + gtk_widget_set_has_window (GTK_WIDGET (ruler), FALSE); + + priv->orientation = GTK_ORIENTATION_HORIZONTAL; + priv->xsrc = 0; + priv->ysrc = 0; + priv->slider_size = 0; + priv->lower = 0; + priv->upper = 0; + priv->position = 0; + priv->max_size = 0; priv->backing_store = NULL; - priv->xsrc = 0; - priv->ysrc = 0; - priv->slider_size = 0; - priv->lower = 0; - priv->upper = 0; - priv->position = 0; - priv->max_size = 0; sp_ruler_set_metric(ruler, SP_PX); } - /** * sp_ruler_invalidate_ticks: * @ruler: the ruler to invalidate @@ -235,22 +236,22 @@ sp_ruler_init (SPRuler *ruler) **/ static void sp_ruler_invalidate_ticks(SPRuler *ruler) { - g_return_if_fail(SP_IS_RULER(ruler)); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + g_return_if_fail(SP_IS_RULER(ruler)); - if(ruler->priv->backing_store == NULL) - return; + if(priv->backing_store == NULL) + return; - sp_ruler_draw_ticks(ruler); - gtk_widget_queue_draw(GTK_WIDGET(ruler)); + sp_ruler_draw_ticks(ruler); + gtk_widget_queue_draw(GTK_WIDGET(ruler)); } /** * sp_ruler_set_range: - * @ruler: the gtkdeprecatedruler + * @ruler: the SPRuler * @lower: the lower limit of the ruler * @upper: the upper limit of the ruler - * @position: the mark on the ruler * @max_size: the maximum size of the ruler used when calculating the space to * leave for the text * @@ -258,14 +259,15 @@ static void sp_ruler_invalidate_ticks(SPRuler *ruler) */ void sp_ruler_set_range (SPRuler *ruler, - gdouble lower, - gdouble upper, - gdouble position, - gdouble max_size) + gdouble lower, + gdouble upper, + gdouble max_size) { + SPRulerPrivate *priv; + g_return_if_fail (SP_IS_RULER (ruler)); - SPRulerPrivate *priv = ruler->priv; + priv = SP_RULER_GET_PRIVATE (ruler); g_object_freeze_notify (G_OBJECT (ruler)); if (priv->lower != lower) @@ -278,11 +280,6 @@ sp_ruler_set_range (SPRuler *ruler, priv->upper = upper; g_object_notify (G_OBJECT (ruler), "upper"); } - if (priv->position != position) - { - priv->position = position; - g_object_notify (G_OBJECT (ruler), "position"); - } if (priv->max_size != max_size) { priv->max_size = max_size; @@ -298,7 +295,6 @@ sp_ruler_set_range (SPRuler *ruler, * @ruler: a #SPRuler * @lower: (allow-none): location to store lower limit of the ruler, or %NULL * @upper: (allow-none): location to store upper limit of the ruler, or %NULL - * @position: (allow-none): location to store the current position of the mark on the ruler, or %NULL * @max_size: location to store the maximum size of the ruler used when calculating * the space to leave for the text, or %NULL. * @@ -309,19 +305,18 @@ void sp_ruler_get_range (SPRuler *ruler, gdouble *lower, gdouble *upper, - gdouble *position, gdouble *max_size) { + SPRulerPrivate *priv; + g_return_if_fail (SP_IS_RULER (ruler)); - SPRulerPrivate *priv = ruler->priv; + priv = SP_RULER_GET_PRIVATE (ruler); if (lower) *lower = priv->lower; if (upper) *upper = priv->upper; - if (position) - *position = priv->position; if (max_size) *max_size = priv->max_size; } @@ -333,7 +328,7 @@ sp_ruler_set_property (GObject *object, GParamSpec *pspec) { SPRuler *ruler = SP_RULER (object); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); switch (prop_id) { @@ -342,23 +337,28 @@ sp_ruler_set_property (GObject *object, gtk_widget_queue_resize (GTK_WIDGET (ruler)); break; case PROP_LOWER: - sp_ruler_set_range (ruler, g_value_get_double (value), priv->upper, - priv->position, priv->max_size); + sp_ruler_set_range (ruler, + g_value_get_double (value), + priv->upper, + priv->max_size); break; case PROP_UPPER: - sp_ruler_set_range (ruler, priv->lower, g_value_get_double (value), - priv->position, priv->max_size); + sp_ruler_set_range (ruler, + priv->lower, + g_value_get_double (value), + priv->max_size); break; case PROP_POSITION: - sp_ruler_set_range (ruler, priv->lower, priv->upper, - g_value_get_double (value), priv->max_size); + sp_ruler_set_position (ruler, g_value_get_double (value)); break; case PROP_MAX_SIZE: - sp_ruler_set_range (ruler, priv->lower, priv->upper, - priv->position, g_value_get_double (value)); + sp_ruler_set_range (ruler, + priv->lower, + priv->upper, + g_value_get_double (value)); break; case PROP_METRIC: - sp_ruler_set_metric(ruler, static_cast(g_value_get_enum (value))); + sp_ruler_set_metric (ruler, static_cast(g_value_get_enum (value))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -373,7 +373,7 @@ sp_ruler_get_property (GObject *object, GParamSpec *pspec) { SPRuler *ruler = SP_RULER (object); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); switch (prop_id) { @@ -413,7 +413,7 @@ sp_ruler_get_property (GObject *object, SPMetric sp_ruler_get_metric(SPRuler *ruler) { g_return_val_if_fail(SP_IS_RULER(ruler), static_cast(0)); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); for (size_t i = 0; i < G_N_ELEMENTS(sp_ruler_metrics); i++) { if (priv->metric == &sp_ruler_metrics[i]) { @@ -427,65 +427,88 @@ SPMetric sp_ruler_get_metric(SPRuler *ruler) } -static void sp_ruler_realize(GtkWidget *widget) +static void +sp_ruler_realize (GtkWidget *widget) { - GtkAllocation allocation; - SPRuler *ruler; - GdkWindow *window; - GdkWindowAttr attributes; - gint attributes_mask; - - ruler = SP_RULER (widget); - - gtk_widget_set_realized (widget, TRUE); + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; + GdkWindowAttr attributes; + gint attributes_mask; - gtk_widget_get_allocation(widget, &allocation); + GTK_WIDGET_CLASS (sp_ruler_parent_class)->realize (widget); + + gtk_widget_get_allocation (widget, &allocation); attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK); - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - - window = gdk_window_new(gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gtk_widget_set_window(widget, window); - gdk_window_set_user_data(window, ruler); - + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + attributes.wclass = GDK_INPUT_ONLY; #if GTK_CHECK_VERSION(3,0,0) - gtk_style_context_set_background(gtk_widget_get_style_context(widget), - window); + attributes.event_mask = (gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK); #else - gtk_widget_style_attach(widget); - gtk_style_set_background(gtk_widget_get_style(widget), - window, GTK_STATE_ACTIVE); + attributes.event_mask = (gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK); #endif + attributes_mask = GDK_WA_X | GDK_WA_Y; + + priv->input_window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (priv->input_window, ruler); + sp_ruler_make_pixmap (ruler); } -static void sp_ruler_unrealize(GtkWidget *widget) +static void +sp_ruler_unrealize(GtkWidget *widget) { - SPRuler *ruler = SP_RULER (widget); - SPRulerPrivate *priv = ruler->priv; + SPRuler *ruler = SP_RULER (widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); if (priv->backing_store) { - cairo_surface_destroy(priv->backing_store); + cairo_surface_destroy (priv->backing_store); priv->backing_store = NULL; } + if (priv->input_window) + { + gdk_window_destroy (priv->input_window); + priv->input_window = NULL; + } + GTK_WIDGET_CLASS (sp_ruler_parent_class)->unrealize (widget); } +static void +sp_ruler_map (GtkWidget *widget) +{ + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); + + GTK_WIDGET_CLASS (sp_ruler_parent_class)->map (widget); + + if (priv->input_window) + gdk_window_show (priv->input_window); +} + +static void +sp_ruler_unmap (GtkWidget *widget) +{ + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); + + if (priv->input_window) + gdk_window_hide (priv->input_window); + + GTK_WIDGET_CLASS (sp_ruler_parent_class)->unmap (widget); +} + static void sp_ruler_size_request(GtkWidget *widget, GtkRequisition *requisition) { @@ -520,25 +543,22 @@ static void sp_ruler_get_preferred_height(GtkWidget *widget, gint *minimal_heigh } #endif -static void sp_ruler_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +static void +sp_ruler_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { - SPRuler *ruler = SP_RULER(widget); - GtkAllocation old_allocation; - gtk_widget_get_allocation(widget, &old_allocation); - - gboolean resized = (old_allocation.width != allocation->width || - old_allocation.height != allocation->height); + SPRuler *ruler = SP_RULER(widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); gtk_widget_set_allocation(widget, allocation); if (gtk_widget_get_realized (widget)) { - gdk_window_move_resize(gtk_widget_get_window(widget), - allocation->x, allocation->y, - allocation->width, allocation->height); - - if(resized) - sp_ruler_make_pixmap (ruler); + gdk_window_move_resize (priv->input_window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + sp_ruler_make_pixmap (ruler); } } @@ -582,26 +602,24 @@ static gboolean sp_ruler_draw(GtkWidget *widget, return FALSE; } -static void sp_ruler_make_pixmap(SPRuler *ruler) + +static void +sp_ruler_make_pixmap (SPRuler *ruler) { - SPRulerPrivate *priv = ruler->priv; - GtkWidget *widget = GTK_WIDGET(ruler); + GtkWidget *widget = GTK_WIDGET (ruler); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); + GtkAllocation allocation; - GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); if (priv->backing_store) - cairo_surface_destroy(priv->backing_store); - - priv->backing_store = gdk_window_create_similar_surface(gtk_widget_get_window(widget), - CAIRO_CONTENT_COLOR, - allocation.width, - allocation.height); + cairo_surface_destroy (priv->backing_store); - priv->xsrc = 0; - priv->ysrc = 0; - - sp_ruler_draw_ticks(ruler); + priv->backing_store = + gdk_window_create_similar_surface (gtk_widget_get_window (widget), + CAIRO_CONTENT_COLOR, + allocation.width, + allocation.height); } @@ -689,7 +707,9 @@ sp_ruler_draw_pos (SPRuler *ruler) cairo_fill (cr); } - sp_ruler_get_range (ruler, &lower, &upper, &position, NULL); + position = sp_ruler_get_position (ruler); + + sp_ruler_get_range (ruler, &lower, &upper, NULL); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { @@ -756,12 +776,53 @@ GtkWidget* sp_ruler_new(GtkOrientation orientation) NULL)); } + +/** + * sp_ruler_set_position: + * @ruler: a #SPRuler + * @position: the position to set the ruler to + * + * This sets the position of the ruler. + */ +void +sp_ruler_set_position (SPRuler *ruler, + gdouble position) +{ + SPRulerPrivate *priv; + + g_return_if_fail (SP_IS_RULER (ruler)); + + priv = SP_RULER_GET_PRIVATE (ruler); + + if (priv->position != position) + { + priv->position = position; + g_object_notify (G_OBJECT (ruler), "position"); + + sp_ruler_draw_pos (ruler); + } +} + +/** + * sp_ruler_get_position: + * @ruler: a #SPRuler + * + * Return value: the current position of the @ruler widget. + */ +gdouble +sp_ruler_get_position (SPRuler *ruler) +{ + g_return_val_if_fail (SP_IS_RULER (ruler), 0.0); + + return SP_RULER_GET_PRIVATE (ruler)->position; +} + static gboolean sp_ruler_motion_notify(GtkWidget *widget, GdkEventMotion *event) { GtkAllocation allocation; SPRuler *ruler = SP_RULER(widget); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); gdk_event_request_motions(event); gint x = event->x; @@ -979,7 +1040,7 @@ void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric) g_return_if_fail(ruler != NULL); g_return_if_fail(SP_IS_RULER (ruler)); g_return_if_fail((unsigned) metric < G_N_ELEMENTS(sp_ruler_metrics)); - SPRulerPrivate *priv = ruler->priv; + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); if (metric == 0) return; diff --git a/src/widgets/ruler.h b/src/widgets/ruler.h index 992d9a385..9874372f1 100644 --- a/src/widgets/ruler.h +++ b/src/widgets/ruler.h @@ -59,20 +59,22 @@ struct _SPRulerMetric }; -GType sp_ruler_get_type (void) G_GNUC_CONST; -GtkWidget* sp_ruler_new (GtkOrientation orientation); -void sp_ruler_set_range (SPRuler *ruler, - gdouble lower, - gdouble upper, - gdouble position, - gdouble max_size); -void sp_ruler_get_range (SPRuler *ruler, - gdouble *lower, - gdouble *upper, - gdouble *position, - gdouble *max_size); -void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric); -SPMetric sp_ruler_get_metric(SPRuler *ruler); +GType sp_ruler_get_type (void) G_GNUC_CONST; +GtkWidget* sp_ruler_new (GtkOrientation orientation); +void sp_ruler_set_position (SPRuler *ruler, + gdouble set_position); +gdouble sp_ruler_get_position (SPRuler *ruler); +void sp_ruler_set_range (SPRuler *ruler, + gdouble lower, + gdouble upper, + gdouble max_size); +void sp_ruler_get_range (SPRuler *ruler, + gdouble *lower, + gdouble *upper, + gdouble *max_size); +void sp_ruler_set_metric (SPRuler *ruler, + SPMetric metric); +SPMetric sp_ruler_get_metric (SPRuler *ruler); #endif /* __SP_RULER_H__ */ -- cgit v1.2.3 From 2a90aa59df1cbc664dae5ec4c5eb8d2a59f22515 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 22 Dec 2012 18:36:14 +0000 Subject: ruler: drop sp_ruler_invalidate_ticks (bzr r11974) --- src/widgets/ruler.cpp | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index d5dcd4709..beb27b999 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -226,26 +226,6 @@ sp_ruler_init (SPRuler *ruler) sp_ruler_set_metric(ruler, SP_PX); } -/** - * sp_ruler_invalidate_ticks: - * @ruler: the ruler to invalidate - * - * For performance reasons, #SPRuler keeps a backbuffer containing the - * prerendered contents of the ticks. To cause a repaint of this buffer, - * call this function instead of gtk_widget_queue_draw(). - **/ -static void sp_ruler_invalidate_ticks(SPRuler *ruler) -{ - SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler); - g_return_if_fail(SP_IS_RULER(ruler)); - - if(priv->backing_store == NULL) - return; - - sp_ruler_draw_ticks(ruler); - gtk_widget_queue_draw(GTK_WIDGET(ruler)); -} - /** * sp_ruler_set_range: @@ -287,7 +267,7 @@ sp_ruler_set_range (SPRuler *ruler, } g_object_thaw_notify (G_OBJECT (ruler)); - sp_ruler_invalidate_ticks(ruler); + gtk_widget_queue_draw (GTK_WIDGET (ruler)); } /** @@ -1049,7 +1029,7 @@ void sp_ruler_set_metric(SPRuler *ruler, SPMetric metric) g_object_notify(G_OBJECT(ruler), "metric"); - sp_ruler_invalidate_ticks(ruler); + gtk_widget_queue_draw (GTK_WIDGET (ruler)); } /* -- cgit v1.2.3 From 15ddbdc55f9f402f08fb6851c08d001f36c06efc Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 22 Dec 2012 18:54:14 +0000 Subject: ruler: Use border widths for Gtk+ 3 rendering (bzr r11975) --- src/widgets/ruler.cpp | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index beb27b999..57c62f881 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -492,18 +492,39 @@ sp_ruler_unmap (GtkWidget *widget) static void sp_ruler_size_request(GtkWidget *widget, GtkRequisition *requisition) { - SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); - GtkStyle *style = gtk_widget_get_style(widget); + SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (widget); + +#if GTK_CHECK_VERSION(3,0,0) + GtkStyleContext *context = gtk_widget_get_style_context (widget); + GtkBorder border; + + gtk_style_context_get_border (context, static_cast(0), &border); + + requisition->width = border.left + border.right; + requisition->height = border.top + border.bottom; +#else + GtkStyle *style = gtk_widget_get_style(widget); +#endif if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { +#if GTK_CHECK_VERSION(3,0,0) + requisition->width += 1; + requisition->height += RULER_WIDTH; +#else requisition->width = style->xthickness * 2 + 1; requisition->height = style->ythickness * 2 + RULER_WIDTH; +#endif } else { +#if GTK_CHECK_VERSION(3,0,0) + requisition->width += RULER_WIDTH; + requisition->height += 1; +#else requisition->width = style->xthickness * 2 + RULER_WIDTH; requisition->height = style->ythickness * 2 + 1; +#endif } } @@ -829,6 +850,7 @@ static void sp_ruler_draw_ticks(SPRuler *ruler) #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkStateFlags state = gtk_widget_get_state_flags (widget); + GtkBorder border; #else GtkStyle *style = gtk_widget_get_style (widget); GtkStateType state = gtk_widget_get_state (widget); @@ -859,10 +881,7 @@ static void sp_ruler_draw_ticks(SPRuler *ruler) gint digit_height = (int) floor (RULER_FONT_SIZE * RULER_FONT_VERTICAL_SPACING / PANGO_SCALE + 0.5); #if GTK_CHECK_VERSION(3,0,0) - GtkBorder padding; - gtk_style_context_get_padding(context, state, &padding); - gint xthickness = padding.left; - gint ythickness = padding.top; + gtk_style_context_get_border (context, static_cast(0), &border); #else gint xthickness = style->xthickness; gint ythickness = style->ythickness; @@ -965,6 +984,15 @@ static void sp_ruler_draw_ticks(SPRuler *ruler) // by a pixel, and jump back on the next redraw). This is suppressed by adding 1e-9 (that's only one nanopixel ;-)) gint pos = int(Inkscape::round((cur - lower) * increment + 1e-12)) - UNUSED_PIXELS; +#if GTK_CHECK_VERSION(3,0,0) + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { + cairo_move_to(cr, pos+0.5, height + border.top); + cairo_line_to(cr, pos+0.5, height - length + border.bottom); + } else { + cairo_move_to(cr, height + border.left - length, pos+0.5); + cairo_line_to(cr, height + border.right, pos+0.5); + } +#else if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_move_to(cr, pos+0.5, height + ythickness); cairo_line_to(cr, pos+0.5, height - length + ythickness); @@ -972,6 +1000,7 @@ static void sp_ruler_draw_ticks(SPRuler *ruler) cairo_move_to(cr, height + xthickness - length, pos+0.5); cairo_line_to(cr, height + xthickness, pos+0.5); } +#endif /* draw label */ double label_spacing_px = fabs((increment*(double)priv->metric->ruler_scale[scale])/priv->metric->subdivide[i]); @@ -992,7 +1021,11 @@ static void sp_ruler_draw_ticks(SPRuler *ruler) for (gint j = 0; j < (int) strlen (unit_str); j++) { digit_str[0] = unit_str[j]; pango_layout_set_text (pango_layout, digit_str, 1); +#if GTK_CHECK_VERSION(3,0,0) + cairo_move_to(cr, border.left + 1, pos + digit_height * (j) + 1); +#else cairo_move_to(cr, xthickness + 1, pos + digit_height * (j) + 1); +#endif pango_cairo_show_layout(cr, pango_layout); } } -- cgit v1.2.3 From d1e043d27a35b00c9e49a2deef1c2ee5bc8b2cc5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 23 Dec 2012 10:55:50 +0100 Subject: Move some code from filter primitives to cairo-utils.cpp. Fix bug in lighting primitives. (bzr r11976) --- src/display/cairo-utils.cpp | 21 +++++++++++++--- src/display/cairo-utils.h | 1 + src/display/nr-filter-blend.cpp | 36 +++------------------------- src/display/nr-filter-colormatrix.cpp | 19 +-------------- src/display/nr-filter-component-transfer.cpp | 18 +------------- src/display/nr-filter-composite.cpp | 36 +++------------------------- src/display/nr-filter-convolve-matrix.cpp | 18 +------------- src/display/nr-filter-diffuselighting.cpp | 9 ++----- src/display/nr-filter-displacement-map.cpp | 19 +-------------- src/display/nr-filter-flood.cpp | 3 --- src/display/nr-filter-gaussian.cpp | 31 ++++-------------------- src/display/nr-filter-image.cpp | 4 ---- src/display/nr-filter-merge.cpp | 13 +--------- src/display/nr-filter-morphology.cpp | 2 -- src/display/nr-filter-offset.cpp | 3 --- src/display/nr-filter-slot.cpp | 2 -- src/display/nr-filter-specularlighting.cpp | 9 ++----- src/display/nr-filter-turbulence.cpp | 2 -- src/display/nr-filter.cpp | 8 +------ 19 files changed, 40 insertions(+), 214 deletions(-) (limited to 'src') diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 92303fed8..692e31837 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -287,9 +287,26 @@ get_cairo_surface_ci(cairo_surface_t *surface) { } } +/** Set the color_interpolation_value for a Cairo surface. + * Transform the surface between sRGB and linearRGB if necessary. */ void set_cairo_surface_ci(cairo_surface_t *surface, SPColorInterpolation ci) { - cairo_surface_set_user_data(surface, &ci_key, GINT_TO_POINTER (ci), NULL); + + if( cairo_surface_get_content( surface ) != CAIRO_CONTENT_ALPHA ) { + + SPColorInterpolation ci_in = get_cairo_surface_ci( surface ); + + if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && + ci == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { + ink_cairo_surface_srgb_to_linear( surface ); + } + if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && + ci == SP_CSS_COLOR_INTERPOLATION_SRGB ) { + ink_cairo_surface_linear_to_srgb( surface ); + } + + cairo_surface_set_user_data(surface, &ci_key, GINT_TO_POINTER (ci), NULL); + } } void @@ -627,7 +644,6 @@ int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) *reinterpret_cast(data + 4*x) = px2; } } - set_cairo_surface_ci( surface, SP_CSS_COLOR_INTERPOLATION_LINEARRGB ); return width * height; } @@ -653,7 +669,6 @@ int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) *reinterpret_cast(data + 4*x) = px2; } } - set_cairo_surface_ci( surface, SP_CSS_COLOR_INTERPOLATION_SRGB ); return width * height; } diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index edaf5ebaa..d240545eb 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -91,6 +91,7 @@ static cairo_user_data_key_t ci_key; SPColorInterpolation get_cairo_surface_ci(cairo_surface_t *surface); void set_cairo_surface_ci(cairo_surface_t *surface, SPColorInterpolation cif); void copy_cairo_surface_ci(cairo_surface_t *in, cairo_surface_t *out); +void convert_cairo_surface_ci(cairo_surface_t *surface, SPColorInterpolation cif); void ink_cairo_set_source_color(cairo_t *ct, SPColor const &color, double opacity); void ink_cairo_set_source_rgba32(cairo_t *ct, guint32 rgba); diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp index 2ada36949..a08191f67 100644 --- a/src/display/nr-filter-blend.cpp +++ b/src/display/nr-filter-blend.cpp @@ -149,47 +149,17 @@ void FilterBlend::render_cairo(FilterSlot &slot) // We may need to transform input surface to correct color interpolation space. The input surface // might be used as input to another primitive but it is likely that all the primitives in a given // filter use the same color interpolation space so we don't copy the input before converting. - // The converting function tags surface with the proper ci value. - // Note: an alpha only surface should not have ci set. - SPColorInterpolation ci_in1 = get_cairo_surface_ci(input1); - SPColorInterpolation ci_in2 = get_cairo_surface_ci(input2); SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; } - if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterColorBlend: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( input1 ); - } - if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterColorBlend: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( input1 ); - } - if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterColorBlend: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( input2 ); - } - if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterColorBlend: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( input2 ); - } + set_cairo_surface_ci( input1, ci_fp ); + set_cairo_surface_ci( input2, ci_fp ); // input2 is the "background" image // out should be ARGB32 if any of the inputs is ARGB32 cairo_surface_t *out = ink_cairo_surface_create_output(input1, input2); - if( cairo_surface_get_content( out ) == CAIRO_CONTENT_COLOR_ALPHA ) { - set_cairo_surface_ci(out, ci_fp ); - } - - // std::cout << "FilterBlend: ci data: " - // << " in1: " << get_cairo_surface_ci(input1) - // << " in2: " << get_cairo_surface_ci(input2) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; + set_cairo_surface_ci( out, ci_fp ); cairo_content_t ct1 = cairo_surface_get_content(input1); cairo_content_t ct2 = cairo_surface_get_content(input2); diff --git a/src/display/nr-filter-colormatrix.cpp b/src/display/nr-filter-colormatrix.cpp index 5d3cf6a9e..77873d523 100644 --- a/src/display/nr-filter-colormatrix.cpp +++ b/src/display/nr-filter-colormatrix.cpp @@ -156,23 +156,11 @@ void FilterColorMatrix::render_cairo(FilterSlot &slot) // We may need to transform input surface to correct color interpolation space. The input surface // might be used as input to another primitive but it is likely that all the primitives in a given // filter use the same color interpolation space so we don't copy the input before converting. - // The converting function tags surface with the proper ci value. - // Note: an alpha only surface should not have ci set. - SPColorInterpolation ci_in = get_cairo_surface_ci(input); SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterColorMatrix: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( input ); - } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterColorMatrix: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( input ); - } + set_cairo_surface_ci( input, ci_fp ); if (type == COLORMATRIX_LUMINANCETOALPHA) { out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_ALPHA); @@ -182,11 +170,6 @@ void FilterColorMatrix::render_cairo(FilterSlot &slot) set_cairo_surface_ci(out, ci_fp); } - // std::cout << "FilterColorMatrix: ci data: " - // << " in1: " << get_cairo_surface_ci(input) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; - switch (type) { case COLORMATRIX_MATRIX: ink_cairo_surface_filter(input, out, FilterColorMatrix::ColorMatrixMatrix(values)); diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index 8efcc9c4d..3bc00d2d7 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -242,28 +242,12 @@ void FilterComponentTransfer::render_cairo(FilterSlot &slot) // We may need to transform input surface to correct color interpolation space. The input surface // might be used as input to another primitive but it is likely that all the primitives in a given // filter use the same color interpolation space so we don't copy the input before converting. - // The converting function tags surface with the proper ci value. - SPColorInterpolation ci_in = get_cairo_surface_ci(input); SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; set_cairo_surface_ci(out, ci_fp ); } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterComponentTransfer: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( input ); - } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterComponentTransfer: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( input ); - } - - // std::cout << "FilterComponentTransfer: ci data: " - // << " in1: " << get_cairo_surface_ci(input) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; + set_cairo_surface_ci( input, ci_fp ); //cairo_surface_t *outtemp = ink_cairo_surface_create_identical(out); ink_cairo_surface_blit(input, out); diff --git a/src/display/nr-filter-composite.cpp b/src/display/nr-filter-composite.cpp index f5ec94a46..f6decad0d 100644 --- a/src/display/nr-filter-composite.cpp +++ b/src/display/nr-filter-composite.cpp @@ -69,45 +69,15 @@ void FilterComposite::render_cairo(FilterSlot &slot) // We may need to transform input surface to correct color interpolation space. The input surface // might be used as input to another primitive but it is likely that all the primitives in a given // filter use the same color interpolation space so we don't copy the input before converting. - // The converting function tags surface with the proper ci value. - // Note: an alpha only surface should not have ci set. - SPColorInterpolation ci_in1 = get_cairo_surface_ci(input1); - SPColorInterpolation ci_in2 = get_cairo_surface_ci(input2); SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; } - if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterColorComposite: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( input1 ); - } - if( ci_in1 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterColorComposite: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( input1 ); - } - if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - std::cout << "FilterColorComposite: srgb -> linear" << std::endl; - //ink_cairo_surface_srgb_to_linear( input2 ); - } - if( ci_in2 == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterColorComposite: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( input2 ); - } + set_cairo_surface_ci( input1, ci_fp ); + set_cairo_surface_ci( input2, ci_fp ); cairo_surface_t *out = ink_cairo_surface_create_output(input1, input2); - if( cairo_surface_get_content( out ) == CAIRO_CONTENT_COLOR_ALPHA ) { - set_cairo_surface_ci(out, ci_fp ); - } - - // std::cout << "FilterComposite: ci data: " - // << " in1: " << get_cairo_surface_ci(input1) - // << " in2: " << get_cairo_surface_ci(input2) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; + set_cairo_surface_ci(out, ci_fp ); if (op == COMPOSITE_ARITHMETIC) { ink_cairo_surface_blend(input1, input2, out, ComposeArithmetic(k1, k2, k3, k4)); diff --git a/src/display/nr-filter-convolve-matrix.cpp b/src/display/nr-filter-convolve-matrix.cpp index 6ee67d126..2aad528a6 100644 --- a/src/display/nr-filter-convolve-matrix.cpp +++ b/src/display/nr-filter-convolve-matrix.cpp @@ -123,28 +123,12 @@ void FilterConvolveMatrix::render_cairo(FilterSlot &slot) // We may need to transform input surface to correct color interpolation space. The input surface // might be used as input to another primitive but it is likely that all the primitives in a given // filter use the same color interpolation space so we don't copy the input before converting. - // The converting function tags surface with the proper ci value. - SPColorInterpolation ci_in = get_cairo_surface_ci(input); SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; set_cairo_surface_ci(out, ci_fp); } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterConvolveMatrix: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( input ); - } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterConvolveMatrix: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( input ); - } - - // std::cout << "FilterConvolveMatrix: ci data: " - // << " in1: " << get_cairo_surface_ci(input) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; + set_cairo_surface_ci( input, ci_fp ); if (bias!=0 && !bias_warning) { g_warning("It is unknown whether Inkscape's implementation of bias in feConvolveMatrix " diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp index bd473eb76..faf56a4ca 100644 --- a/src/display/nr-filter-diffuselighting.cpp +++ b/src/display/nr-filter-diffuselighting.cpp @@ -129,14 +129,9 @@ void FilterDiffuseLighting::render_cairo(FilterSlot &slot) // Only alpha channel of input is used, no need to check input color_interpolation_filter value. SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { - set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); - set_cairo_surface_ci(out, ci_fp ); + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; } - - // std::cout << "FilterDiffuseLighting: ci data: " - // << " in1: " << get_cairo_surface_ci(input) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; + set_cairo_surface_ci(out, ci_fp ); Geom::Rect slot_area = slot.get_slot_area(); Geom::Point p = slot_area.min(); diff --git a/src/display/nr-filter-displacement-map.cpp b/src/display/nr-filter-displacement-map.cpp index 909e11f50..1b979fa6c 100644 --- a/src/display/nr-filter-displacement-map.cpp +++ b/src/display/nr-filter-displacement-map.cpp @@ -80,28 +80,11 @@ void FilterDisplacementMap::render_cairo(FilterSlot &slot) // We may need to transform map surface to correct color interpolation space. The map surface // might be used as input to another primitive but it is likely that all the primitives in a given // filter use the same color interpolation space so we don't copy the map before converting. - // The converting function tags surface with the proper ci value. - SPColorInterpolation ci_map = get_cairo_surface_ci(map); SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; } - if( ci_map == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterDisplacementMap: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( map ); - } - if( ci_map == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterDisplacementMap: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( map ); - } - - // std::cout << "FilterDisplacementMap: ci data: " - // << " texture: " << get_cairo_surface_ci(texture) - // << " map: " << get_cairo_surface_ci(map) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; + set_cairo_surface_ci( map, ci_fp ); Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); double scalex = scale * trans.expansionX(); diff --git a/src/display/nr-filter-flood.cpp b/src/display/nr-filter-flood.cpp index 649d4609f..7117e0343 100644 --- a/src/display/nr-filter-flood.cpp +++ b/src/display/nr-filter-flood.cpp @@ -62,9 +62,6 @@ void FilterFlood::render_cairo(FilterSlot &slot) set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); } - // std::cout << "FilterFlood: ci data: out: " - // << get_cairo_surface_ci(out) << std::endl; - // Get filter primitive area in user units Geom::Rect fp = filter_primitive_area( slot.get_units() ); diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index 3b29e825d..9d7c32585 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -556,26 +556,11 @@ void FilterGaussian::render_cairo(FilterSlot &slot) // We may need to transform input surface to correct color interpolation space. The input surface // might be used as input to another primitive but it is likely that all the primitives in a given // filter use the same color interpolation space so we don't copy the input before converting. - // The converting function tags surface with the proper ci value. - // Note: an alpha only surface should not have ci set. - SPColorInterpolation ci_in = get_cairo_surface_ci(in); SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterGaussian: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( in ); - } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterGaussian: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( in ); - } - - // std::cout << "FilterGaussian: ci data: in: " - // << get_cairo_surface_ci( in ) << std::endl; + set_cairo_surface_ci( in, ci_fp ); // zero deviation = no change in output if (_deviation_x <= 0 && _deviation_y <= 0) { @@ -684,20 +669,14 @@ void FilterGaussian::render_cairo(FilterSlot &slot) cairo_paint(ct); cairo_destroy(ct); - if( cairo_surface_get_content( upsampled ) == CAIRO_CONTENT_COLOR_ALPHA ) { - set_cairo_surface_ci( upsampled, ci_fp ); - } - // std::cout << "FilterGaussian: ci data: resampled: " - // << get_cairo_surface_ci(upsampled) << std::endl; + set_cairo_surface_ci( upsampled, ci_fp ); + slot.set(_output, upsampled); cairo_surface_destroy(upsampled); cairo_surface_destroy(downsampled); } else { - if( cairo_surface_get_content( downsampled ) == CAIRO_CONTENT_COLOR_ALPHA ) { - set_cairo_surface_ci( downsampled, ci_fp ); - } - // std::cout << "FilterGaussian: ci data: downsampled: " - // << get_cairo_surface_ci(downsampled) << std::endl; + set_cairo_surface_ci( downsampled, ci_fp ); + slot.set(_output, downsampled); cairo_surface_destroy(downsampled); } diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 8aae29cbe..fca8fdba3 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -122,8 +122,6 @@ void FilterImage::render_cairo(FilterSlot &slot) // For the moment, we'll assume that any image is in sRGB color space set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB); - // std::cout << "FilterImage: ci set to: " - // << get_cairo_surface_ci(out) << std::endl; slot.set(_output, out); cairo_surface_destroy(out); @@ -192,8 +190,6 @@ void FilterImage::render_cairo(FilterSlot &slot) // For the moment, we'll assume that any image is in sRGB color space set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB); - // std::cout << "FilterImage: ci set to: " - // << get_cairo_surface_ci(out) << std::endl; cairo_t *ct = cairo_create(out); cairo_translate(ct, -sa.min()[Geom::X], -sa.min()[Geom::Y]); diff --git a/src/display/nr-filter-merge.cpp b/src/display/nr-filter-merge.cpp index 4d3862a33..2b9a24f25 100644 --- a/src/display/nr-filter-merge.cpp +++ b/src/display/nr-filter-merge.cpp @@ -59,18 +59,7 @@ void FilterMerge::render_cairo(FilterSlot &slot) for (std::vector::iterator i = _input_image.begin(); i != _input_image.end(); ++i) { cairo_surface_t *in = slot.getcairo(*i); - SPColorInterpolation ci_in = get_cairo_surface_ci(in); - //std::cout << "FilterMerge: slot: ci: " << ci_in << std::endl; - if( ci_in == SP_CSS_COLOR_INTERPOLATION_SRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "FilterMerge: srgb -> linear" << std::endl; - ink_cairo_surface_srgb_to_linear( in ); - } - if( ci_in == SP_CSS_COLOR_INTERPOLATION_LINEARRGB && - ci_fp == SP_CSS_COLOR_INTERPOLATION_SRGB ) { - //std::cout << "FilterMerge: linear -> srgb" << std::endl; - ink_cairo_surface_linear_to_srgb( in ); - } + set_cairo_surface_ci( in, ci_fp ); cairo_set_source_surface(out_ct, in, 0, 0); cairo_paint(out_ct); } diff --git a/src/display/nr-filter-morphology.cpp b/src/display/nr-filter-morphology.cpp index 7447b76fe..b058307cf 100644 --- a/src/display/nr-filter-morphology.cpp +++ b/src/display/nr-filter-morphology.cpp @@ -195,8 +195,6 @@ void FilterMorphology::render_cairo(FilterSlot &slot) // color_interpolation_filters for out same as input. See spec (DisplacementMap). copy_cairo_surface_ci(input, out); - // std::cout << "FilterMorphology: ci set to: " - // << get_cairo_surface_ci(out) << std::endl; if (Operator == MORPHOLOGY_OPERATOR_DILATE) { if (bpp == 1) { diff --git a/src/display/nr-filter-offset.cpp b/src/display/nr-filter-offset.cpp index 3543de6df..01d6ffe56 100644 --- a/src/display/nr-filter-offset.cpp +++ b/src/display/nr-filter-offset.cpp @@ -38,9 +38,6 @@ void FilterOffset::render_cairo(FilterSlot &slot) // color_interpolation_filters for out same as in. See spec (DisplacementMap). copy_cairo_surface_ci(in, out); - // std::cout << "FilterOffset: ci data: out: " - // << get_cairo_surface_ci(out) << std::endl; - cairo_t *ct = cairo_create(out); Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp index 64c5143ff..fe67972d6 100644 --- a/src/display/nr-filter-slot.cpp +++ b/src/display/nr-filter-slot.cpp @@ -84,13 +84,11 @@ cairo_surface_t *FilterSlot::getcairo(int slot_nr) case NR_FILTER_SOURCEGRAPHIC: { cairo_surface_t *tr = _get_transformed_source_graphic(); _set_internal(NR_FILTER_SOURCEGRAPHIC, tr); - //std::cout << "Source Graphic: ci data: " << get_cairo_surface_ci( tr ) << std::endl; cairo_surface_destroy(tr); } break; case NR_FILTER_BACKGROUNDIMAGE: { cairo_surface_t *bg = _get_transformed_background(); _set_internal(NR_FILTER_BACKGROUNDIMAGE, bg); - //std::cout << "Background Image: ci data: " << get_cairo_surface_ci( bg ) << std::endl; cairo_surface_destroy(bg); } break; case NR_FILTER_SOURCEALPHA: { diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp index 4cf8f319d..50f1b48c5 100644 --- a/src/display/nr-filter-specularlighting.cpp +++ b/src/display/nr-filter-specularlighting.cpp @@ -142,14 +142,9 @@ void FilterSpecularLighting::render_cairo(FilterSlot &slot) // Only alpha channel of input is used, no need to check input color_interpolation_filter value. SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO; if( _style ) { - set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); - set_cairo_surface_ci(out, ci_fp ); + ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed; } - - // std::cout << "FilterSpecularLighting: ci data: " - // << " in1: " << get_cairo_surface_ci(input) - // << " out: " << get_cairo_surface_ci(out) - // << std::endl; + set_cairo_surface_ci(out, ci_fp ); Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb(); Geom::Point p = slot.get_slot_area().min(); diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index e2b52a1d4..76b877fbc 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -379,8 +379,6 @@ void FilterTurbulence::render_cairo(FilterSlot &slot) if( _style ) { set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed ); } - // std::cout << "FilterTurbulance: ci data: out: " - // << get_cairo_surface_ci(out) << std::endl; if (!gen->ready()) { Geom::Point ta(fTileX, fTileY); diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index a29ac551a..eeba94d7c 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -161,14 +161,8 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D Geom::Point origin = graphic.targetLogicalBounds().min(); cairo_surface_t *result = slot.get_result(_output_slot); - // std::cout << "Filter: result: ci data: " - // << get_cairo_surface_ci(result) << std::endl; - // Assume for the moment that we paint the filter in sRGB - if( get_cairo_surface_ci(result) == SP_CSS_COLOR_INTERPOLATION_LINEARRGB ) { - //std::cout << "Filter: result: linear -> sRGB" << std::endl; - ink_cairo_surface_linear_to_srgb( result ); - } + set_cairo_surface_ci( result, SP_CSS_COLOR_INTERPOLATION_SRGB ); graphic.setSource(result, origin[Geom::X], origin[Geom::Y]); graphic.setOperator(CAIRO_OPERATOR_SOURCE); -- cgit v1.2.3