diff options
Diffstat (limited to 'eel/eel-canvas-rect-ellipse.c')
-rw-r--r-- | eel/eel-canvas-rect-ellipse.c | 467 |
1 files changed, 119 insertions, 348 deletions
diff --git a/eel/eel-canvas-rect-ellipse.c b/eel/eel-canvas-rect-ellipse.c index c637769d..d0e4a592 100644 --- a/eel/eel-canvas-rect-ellipse.c +++ b/eel/eel-canvas-rect-ellipse.c @@ -60,8 +60,7 @@ enum PROP_OUTLINE_COLOR, PROP_OUTLINE_COLOR_GDK, PROP_OUTLINE_COLOR_RGBA, - PROP_FILL_STIPPLE, - PROP_OUTLINE_STIPPLE, + PROP_OUTLINE_STIPPLING, PROP_WIDTH_PIXELS, PROP_WIDTH_UNITS }; @@ -69,7 +68,6 @@ enum static void eel_canvas_re_class_init (EelCanvasREClass *klass); static void eel_canvas_re_init (EelCanvasRE *re); -static void eel_canvas_re_destroy (GtkObject *object); static void eel_canvas_re_set_property (GObject *object, guint param_id, const GValue *value, @@ -134,11 +132,9 @@ static void eel_canvas_re_class_init (EelCanvasREClass *klass) { GObjectClass *gobject_class; - GtkObjectClass *object_class; EelCanvasItemClass *item_class; gobject_class = (GObjectClass *) klass; - object_class = (GtkObjectClass *) klass; item_class = (EelCanvasItemClass *) klass; re_parent_class = g_type_class_peek_parent (klass); @@ -190,12 +186,6 @@ eel_canvas_re_class_init (EelCanvasREClass *klass) G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, - PROP_FILL_STIPPLE, - g_param_spec_object ("fill-stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - G_PARAM_READWRITE)); - g_object_class_install_property - (gobject_class, PROP_OUTLINE_COLOR, g_param_spec_string ("outline-color", NULL, NULL, NULL, @@ -212,12 +202,11 @@ eel_canvas_re_class_init (EelCanvasREClass *klass) g_param_spec_uint ("outline-color-rgba", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property - (gobject_class, - PROP_OUTLINE_STIPPLE, - g_param_spec_object ("outline-stipple", NULL, NULL, - GDK_TYPE_DRAWABLE, - G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_OUTLINE_STIPPLING, + g_param_spec_boolean ("outline-stippling", NULL, NULL, + FALSE, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_WIDTH_PIXELS, @@ -231,8 +220,6 @@ eel_canvas_re_class_init (EelCanvasREClass *klass) 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); - object_class->destroy = eel_canvas_re_destroy; - item_class->realize = eel_canvas_re_realize; item_class->unrealize = eel_canvas_re_unrealize; item_class->translate = eel_canvas_re_translate; @@ -249,30 +236,6 @@ eel_canvas_re_init (EelCanvasRE *re) re->width = 0.0; } -static void -eel_canvas_re_destroy (GtkObject *object) -{ - EelCanvasRE *re; - - g_return_if_fail (object != NULL); - g_return_if_fail (EEL_IS_CANVAS_RE (object)); - - re = EEL_CANVAS_RE (object); - - /* remember, destroy can be run multiple times! */ - - if (re->fill_stipple) - g_object_unref (re->fill_stipple); - re->fill_stipple = NULL; - - if (re->outline_stipple) - g_object_unref (re->outline_stipple); - re->outline_stipple = NULL; - - if (GTK_OBJECT_CLASS (re_parent_class)->destroy) - (* GTK_OBJECT_CLASS (re_parent_class)->destroy) (object); -} - static void get_bounds (EelCanvasRE *re, double *px1, double *py1, double *px2, double *py2) { EelCanvasItem *item; @@ -312,60 +275,6 @@ static void get_bounds (EelCanvasRE *re, double *px1, double *py1, double *px2, *py2 += 2; } -/* Convenience function to set a GC's foreground color to the specified pixel value */ -static void -set_gc_foreground (GdkGC *gc, gulong pixel) -{ - GdkColor c; - - if (!gc) - return; - - c.pixel = pixel; - gdk_gc_set_foreground (gc, &c); -} - -/* Sets the stipple pattern for the specified gc */ -static void -set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure) -{ - if (*internal_stipple && !reconfigure) - g_object_unref (*internal_stipple); - - *internal_stipple = stipple; - if (stipple && !reconfigure) - g_object_ref (stipple); - - if (gc) - { - if (stipple) - { - gdk_gc_set_stipple (gc, stipple); - gdk_gc_set_fill (gc, GDK_STIPPLED); - } - else - gdk_gc_set_fill (gc, GDK_SOLID); - } -} - -/* Recalculate the outline width of the rectangle/ellipse and set it in its GC */ -static void -set_outline_gc_width (EelCanvasRE *re) -{ - int width; - - if (!re->outline_gc) - return; - - if (re->width_pixels) - width = (int) re->width; - else - width = (int) (re->width * re->item.canvas->pixels_per_unit + 0.5); - - gdk_gc_set_line_attributes (re->outline_gc, width, - GDK_LINE_SOLID, GDK_CAP_PROJECTING, GDK_JOIN_MITER); -} - static void eel_canvas_re_set_fill (EelCanvasRE *re, gboolean fill_set) { @@ -396,14 +305,12 @@ eel_canvas_re_set_property (GObject *object, EelCanvasRE *re; GdkColor color = { 0, 0, 0, 0, }; GdkColor *pcolor; - int have_pixel; g_return_if_fail (object != NULL); g_return_if_fail (EEL_IS_CANVAS_RE (object)); item = EEL_CANVAS_ITEM (object); re = EEL_CANVAS_RE (object); - have_pixel = FALSE; switch (param_id) { @@ -455,12 +362,7 @@ eel_canvas_re_set_property (GObject *object, if (pcolor) { - GdkColormap *colormap; - color = *pcolor; - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - have_pixel = TRUE; } re->fill_color = ((color.red & 0xff00) << 16 | @@ -477,13 +379,6 @@ eel_canvas_re_set_property (GObject *object, #ifdef VERBOSE g_print ("re fill color = %08x\n", re->fill_color); #endif - if (have_pixel) - re->fill_pixel = color.pixel; - else - re->fill_pixel = eel_canvas_get_color_pixel (item->canvas, re->fill_color); - - set_gc_foreground (re->fill_gc, re->fill_pixel); - eel_canvas_item_request_redraw (item); break; @@ -511,13 +406,7 @@ eel_canvas_re_set_property (GObject *object, if (pcolor) { - GdkColormap *colormap; - color = *pcolor; - colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_rgb_find_color (colormap, &color); - - have_pixel = TRUE; } re->outline_color = ((color.red & 0xff00) << 16 | @@ -534,30 +423,18 @@ eel_canvas_re_set_property (GObject *object, #ifdef VERBOSE g_print ("re outline color %x %x %x\n", color.red, color.green, color.blue); #endif - if (have_pixel) - re->outline_pixel = color.pixel; - else - re->outline_pixel = eel_canvas_get_color_pixel (item->canvas, - re->outline_color); - - set_gc_foreground (re->outline_gc, re->outline_pixel); - eel_canvas_item_request_redraw (item); break; - case PROP_FILL_STIPPLE: - set_stipple (re->fill_gc, &re->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); + case PROP_OUTLINE_STIPPLING: + re->outline_stippling = g_value_get_boolean (value); - break; - - case PROP_OUTLINE_STIPPLE: - set_stipple (re->outline_gc, &re->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); - break; + eel_canvas_item_request_redraw (item); + break; case PROP_WIDTH_PIXELS: re->width = g_value_get_uint (value); re->width_pixels = TRUE; - set_outline_gc_width (re); eel_canvas_item_request_update (item); break; @@ -565,7 +442,6 @@ eel_canvas_re_set_property (GObject *object, case PROP_WIDTH_UNITS: re->width = fabs (g_value_get_double (value)); re->width_pixels = FALSE; - set_outline_gc_width (re); eel_canvas_item_request_update (item); break; @@ -583,10 +459,14 @@ static void get_color_value (EelCanvasRE *re, gulong pixel, GValue *value) { GdkColor color; - EelCanvasItem *item = (EelCanvasItem *) re; - GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); - gdk_colormap_query_color (colormap, pixel, &color); + color.red = (pixel >> 16) & 0xFF; + color.green = (pixel >> 8) & 0xFF; + color.blue = pixel & 0xFF; + color.red |= color.red << 8; + color.green |= color.green << 8; + color.blue |= color.blue << 8; + g_value_set_boxed (value, &color); } @@ -622,11 +502,11 @@ eel_canvas_re_get_property (GObject *object, break; case PROP_FILL_COLOR_GDK: - get_color_value (re, re->fill_pixel, value); + get_color_value (re, re->fill_color, value); break; case PROP_OUTLINE_COLOR_GDK: - get_color_value (re, re->outline_pixel, value); + get_color_value (re, re->outline_color, value); break; case PROP_FILL_COLOR_RGBA: @@ -637,13 +517,9 @@ eel_canvas_re_get_property (GObject *object, g_value_set_uint (value, re->outline_color); break; - case PROP_FILL_STIPPLE: - g_value_set_object (value, (GObject *) re->fill_stipple); - break; - - case PROP_OUTLINE_STIPPLE: - g_value_set_object (value, (GObject *) re->outline_stipple); - break; + case PROP_OUTLINE_STIPPLING: + g_value_set_boolean (value, re->outline_stippling); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -652,16 +528,6 @@ eel_canvas_re_get_property (GObject *object, } static void -set_colors_and_stipples (EelCanvasRE *re) -{ - set_gc_foreground (re->fill_gc, re->fill_pixel); - set_gc_foreground (re->outline_gc, re->outline_pixel); - set_stipple (re->fill_gc, &re->fill_stipple, re->fill_stipple, TRUE); - set_stipple (re->outline_gc, &re->outline_stipple, re->outline_stipple, TRUE); - set_outline_gc_width (re); -} - -static void eel_canvas_re_update_shared (EelCanvasItem *item, double i2w_dx, double i2w_dy, int flags) { EelCanvasRE *re; @@ -674,8 +540,6 @@ eel_canvas_re_update_shared (EelCanvasItem *item, double i2w_dx, double i2w_dy, if (re_parent_class->update) (* re_parent_class->update) (item, i2w_dx, i2w_dy, flags); - set_colors_and_stipples (re); - #ifdef OLD_XFORM recalc_bounds (re); #endif @@ -694,12 +558,6 @@ eel_canvas_re_realize (EelCanvasItem *item) if (re_parent_class->realize) (* re_parent_class->realize) (item); - re->fill_gc = gdk_gc_new (gtk_layout_get_bin_window (&item->canvas->layout)); - re->fill_pixel = eel_canvas_get_color_pixel (item->canvas, re->fill_color); - re->outline_gc = gdk_gc_new (gtk_layout_get_bin_window (&item->canvas->layout)); - re->outline_pixel = eel_canvas_get_color_pixel (item->canvas, re->outline_color); - set_colors_and_stipples (re); - #ifdef OLD_XFORM (* EEL_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0); #endif @@ -712,11 +570,6 @@ eel_canvas_re_unrealize (EelCanvasItem *item) re = EEL_CANVAS_RE (item); - g_object_unref (re->fill_gc); - re->fill_gc = NULL; - g_object_unref (re->outline_gc); - re->outline_gc = NULL; - if (re_parent_class->unrealize) (* re_parent_class->unrealize) (item); } @@ -768,7 +621,11 @@ static void eel_canvas_rect_init (EelCanvasRect *rect); static void eel_canvas_rect_finalize (GObject *object); static void eel_canvas_rect_realize (EelCanvasItem *item); +#if GTK_CHECK_VERSION(3,0,0) +static void eel_canvas_rect_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region); +#else static void eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); +#endif static double eel_canvas_rect_point (EelCanvasItem *item, double x, double y, int cx, int cy, EelCanvasItem **actual_item); @@ -883,110 +740,24 @@ eel_canvas_rect_realize (EelCanvasItem *item) static void -render_rect_alpha (EelCanvasRect *rect, - GdkDrawable *drawable, - int x, int y, - int width, int height, - guint32 rgba) +eel_canvas_set_source_color (cairo_t *cr, + guint rgba) { - GdkPixbuf *pixbuf; - guchar *data; - int rowstride, i; - guchar r, g, b, a; - EelCanvasRectPrivate *priv; - - if (width <= 0 || height <= 0 ) - { - return; - } - - priv = rect->priv; - - r = (rgba >> 24) & 0xff; - g = (rgba >> 16) & 0xff; - b = (rgba >> 8) & 0xff; - a = (rgba >> 0) & 0xff; - -#ifdef HAVE_RENDER - /* Every visual is not guaranteed to have a matching - * XRenderPictFormat. So make sure that format is not null before - * trying to render using Xrender calls. - */ - if (priv->use_render && (priv->format != NULL)) - { - GdkDrawable *real_drawable; - int x_offset, y_offset; - - Display *dpy; - Picture pict; - XRenderPictureAttributes attributes; - XRenderColor color; - - gdk_window_get_internal_paint_info (drawable, &real_drawable, - &x_offset, &y_offset); - - dpy = gdk_x11_drawable_get_xdisplay (real_drawable); - - pict = XRenderCreatePicture (dpy, - gdk_x11_drawable_get_xid (real_drawable), - priv->format, - 0, - &attributes); - - - /* Convert to premultiplied alpha: */ - r = r * a / 255; - g = g * a / 255; - b = b * a / 255; - - color.red = (r << 8) + r; - color.green = (g << 8) + g; - color.blue = (b << 8) + b; - color.alpha = (a << 8) + a; - - XRenderFillRectangle (dpy, - PictOpOver, - pict, - &color, - x - x_offset, y - y_offset, - width, height); - - XRenderFreePicture (dpy, pict); - - return; - } -#endif - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); - data = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - r = (rgba >> 24) & 0xff; - g = (rgba >> 16) & 0xff; - b = (rgba >> 8) & 0xff; - a = (rgba >> 0) & 0xff; - - for (i = 0; i < width*4; ) - { - data[i++] = r; - data[i++] = g; - data[i++] = b; - data[i++] = a; - } - - for (i = 1; i < height; i++) - { - memcpy (data + i*rowstride, data, width*4); - } - - gdk_draw_pixbuf (drawable, NULL, pixbuf, - 0, 0, x, y, width, height, - GDK_RGB_DITHER_NONE, 0, 0); - g_object_unref (pixbuf); + cairo_set_source_rgba (cr, + ((rgba >> 24) & 0xff) / 255., + ((rgba >> 16) & 0xff) / 255., + ((rgba >> 8) & 0xff) / 255., + ((rgba >> 0) & 0xff) / 255.); } - +#define DASH_ON 0.8 +#define DASH_OFF 1.7 static void +#if GTK_CHECK_VERSION(3,0,0) +eel_canvas_rect_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region) +#else eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose) +#endif { EelCanvasRE *re; double x1, y1, x2, y2; @@ -1008,69 +779,55 @@ eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose eel_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1); eel_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2); + if (cx2 <= cx1 || cy2 <= cy1 ) { + return; + } + +#if GTK_CHECK_VERSION(3,0,0) + cairo_save (cr); +#else + cairo_t *cr = gdk_cairo_create (drawable); + gdk_cairo_region (cr, expose->region); + cairo_clip (cr); +#endif + if (re->fill_set) { - if ((re->fill_color & 0xff) != 255) - { - GdkRectangle *rectangles; - gint i, n_rectangles; - GdkRectangle draw_rect; - GdkRectangle part; - - draw_rect.x = cx1; - draw_rect.y = cy1; - draw_rect.width = cx2 - cx1 + 1; - draw_rect.height = cy2 - cy1 + 1; - - /* For alpha mode, only render the parts of the region - that are actually exposed */ - gdk_region_get_rectangles (expose->region, - &rectangles, - &n_rectangles); - - for (i = 0; i < n_rectangles; i++) - { - if (gdk_rectangle_intersect (&rectangles[i], - &draw_rect, - &part)) - { - render_rect_alpha (EEL_CANVAS_RECT (item), - drawable, - part.x, part.y, - part.width, part.height, - re->fill_color); - } - } - - g_free (rectangles); - } - else - { - if (re->fill_stipple) - eel_canvas_set_stipple_origin (item->canvas, re->fill_gc); - - gdk_draw_rectangle (drawable, - re->fill_gc, - TRUE, - cx1, cy1, - cx2 - cx1 + 1, - cy2 - cy1 + 1); - } + eel_canvas_set_source_color (cr, re->fill_color); + cairo_rectangle (cr, + cx1, cy1, + cx2 - cx1 + 1, + cy2 - cy1 + 1); + cairo_fill (cr); } if (re->outline_set) { - if (re->outline_stipple) - eel_canvas_set_stipple_origin (item->canvas, re->outline_gc); - - gdk_draw_rectangle (drawable, - re->outline_gc, - FALSE, - cx1, - cy1, - cx2 - cx1, - cy2 - cy1); + eel_canvas_set_source_color (cr, re->outline_color); + if (re->width_pixels) { + cairo_set_line_width (cr, (int) re->width); + } else { + cairo_set_line_width (cr, (int) (re->width * re->item.canvas->pixels_per_unit + 0.5)); + } + + if (re->outline_stippling) { + double dash[2] = { DASH_ON, DASH_OFF }; + + cairo_set_dash (cr, dash, G_N_ELEMENTS (dash), 0); + } + + cairo_rectangle (cr, + cx1 + 0.5, cy1 + 0.5, + cx2 - cx1, + cy2 - cy1); + cairo_stroke (cr); } + +#if GTK_CHECK_VERSION(3,0,0) + cairo_restore (cr); +#else + cairo_destroy (cr); +#endif } static double @@ -1266,7 +1023,11 @@ eel_canvas_rect_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, gint static void eel_canvas_ellipse_class_init (EelCanvasEllipseClass *klass); +#if GTK_CHECK_VERSION(3,0,0) +static void eel_canvas_ellipse_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region); +#else static void eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); +#endif static double eel_canvas_ellipse_point (EelCanvasItem *item, double x, double y, int cx, int cy, EelCanvasItem **actual_item); @@ -1314,7 +1075,11 @@ eel_canvas_ellipse_class_init (EelCanvasEllipseClass *klass) } static void +#if GTK_CHECK_VERSION(3,0,0) +eel_canvas_ellipse_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region) +#else eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose) +#endif { EelCanvasRE *re; int x1, y1, x2, y2; @@ -1337,37 +1102,43 @@ eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExp re->y2 + i2w_dy, &x2, &y2); +#if GTK_CHECK_VERSION(3,0,0) + cairo_save (cr); +#else + cairo_t *cr = gdk_cairo_create (drawable); + gdk_cairo_region (cr, expose->region); + cairo_clip (cr); +#endif + + cairo_save (cr); + cairo_translate (cr, (x1 + x2) / 2., (y1 + y2) / 2.); + cairo_scale (cr, (x2 - x1), (y2 - y1)); + cairo_arc (cr, 0, 0, 1, 0, 2 * G_PI); + cairo_restore (cr); + if (re->fill_set) { - if (re->fill_stipple) - eel_canvas_set_stipple_origin (item->canvas, re->fill_gc); - - gdk_draw_arc (drawable, - re->fill_gc, - TRUE, - x1, - y1, - x2 - x1, - y2 - y1, - 0 * 64, - 360 * 64); + eel_canvas_set_source_color (cr, re->fill_color); + cairo_fill_preserve (cr); } if (re->outline_set) { - if (re->outline_stipple) - eel_canvas_set_stipple_origin (item->canvas, re->outline_gc); - - gdk_draw_arc (drawable, - re->outline_gc, - FALSE, - x1, - y1, - x2 - x1, - y2 - y1, - 0 * 64, - 360 * 64); + eel_canvas_set_source_color (cr, re->outline_color); + if (re->width_pixels) { + cairo_set_line_width (cr, (int) re->width); + } else { + cairo_set_line_width (cr, (int) (re->width * re->item.canvas->pixels_per_unit + 0.5)); + } + + cairo_stroke_preserve (cr); } + +#if GTK_CHECK_VERSION(3,0,0) + cairo_restore (cr); +#else + cairo_destroy (cr); +#endif } static double |