summaryrefslogtreecommitdiff
path: root/eel/eel-canvas-rect-ellipse.c
diff options
context:
space:
mode:
Diffstat (limited to 'eel/eel-canvas-rect-ellipse.c')
-rw-r--r--eel/eel-canvas-rect-ellipse.c467
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