diff options
author | Owen Taylor <otaylor@redhat.com> | 2005-03-17 01:54:40 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2005-03-17 01:54:40 +0000 |
commit | 09d7eafb15099362c0ed611d775b1f2fe5f17f94 (patch) | |
tree | 288fc18e7d665e5e897409489e409c017efece2d /gtk | |
parent | eebd4f1c4bba4d1a2b9a5e0cfd9fd34f318ee84d (diff) | |
download | gtk+-09d7eafb15099362c0ed611d775b1f2fe5f17f94.tar.gz |
Switch set_cairo_target() virtual function to ref_cairo_surface()
2005-03-15 Owen Taylor <otaylor@redhat.com>
* gdk/gdkdrawable.h gdk/gdkdraw.c gdk/gdkpixmap.c gdk/gdkwindow.c
gdk/x11/gdkdrawable-x11.c gdk/x11/gdkpixmap-x11.c gdk/x11/gdkwindow-x11.c
gdk/gdkinternals.h: Switch set_cairo_target() virtual function to
ref_cairo_surface()
* gdk/gdkdrawable.h gdk/gdkdraw.h: Switch set_cairo_target() virtual
function to create_cairo_context()
* gdk/gdkwindow.c: Clear double buffer pixmaps with Cairo.
* gdk/x11/gdkwindow-x11.c: Keep all components in GdkWindowObject.bg_color,
not just the pixel.
* tests/testcairo.c: Update for create_cairo_context()
* gdk/gdkdraw.c (gdk_draw_trapezoids, gdk_draw_glyphs[_transformed]):
Reimplement in terms of Cairo, bypass the vtable entries.
* gdk/x11/gdkdrawable-x11.[ch] gdk/x11/gdkdisplay-x11.[ch]
gdk/x11/gdkgc-x11.c gdk/x11/gdkpango-x11.c
gdk/x11/gdkprivate-x11.h gdk/x11/Makefile.am: Remove
implementation of draw_trapezoids / draw_glyphs[_transformed].
* gdk/gdkpango.c: Switch GdkPangoRenderer to use Cairo
* gdk/gdkpango.c gdk/x11/gdkpango-x11.c: Move
gdk_pango_context_get_for_screen() into the backend independent code.
* gdk/x11/gdkdrawable-x11.[ch]: Remove Xft use, use RENDER directly
for drawing images.
* gdk/gdkdrawable.h gdk/x11/gdkdrawable-x11.c: Remove
gdk_draw_rectangle_alpha_libgtk_only.
* gdk/gdkpixbuf.h gdk/gdkpixbuf-render.c: Add
gdk_pixbuf_set_as_cairo_source()
* gdk/gdk.symbols: Update
* gtk/gtkcolorsel.c gtk/gtkhsv.c gtk/gtkiconview.c gtk/gtkruler.[ch]
gtk/gtk[hv]ruler.c: Convert to Cairo rendering.
* gtk/gtkstyle.c (gtk_default_draw_check, gtk_default_draw_focus,
gtk_default_draw_option): Switch to Cairo. Simplify the checkbutton,
radio button style for now to get something more scalable.
* gtk/gtksettings.c: #if 0 out the code to use PangoXft for hinting/
antialiasing/dpi settings.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkcolorsel.c | 191 | ||||
-rw-r--r-- | gtk/gtkhruler.c | 58 | ||||
-rw-r--r-- | gtk/gtkhsv.c | 341 | ||||
-rw-r--r-- | gtk/gtkiconview.c | 121 | ||||
-rw-r--r-- | gtk/gtkruler.c | 3 | ||||
-rw-r--r-- | gtk/gtkruler.h | 2 | ||||
-rw-r--r-- | gtk/gtksettings.c | 8 | ||||
-rw-r--r-- | gtk/gtkstyle.c | 741 | ||||
-rw-r--r-- | gtk/gtkvruler.c | 58 |
9 files changed, 650 insertions, 873 deletions
diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c index 7baea1367f..7c6375bd97 100644 --- a/gtk/gtkcolorsel.c +++ b/gtk/gtkcolorsel.c @@ -165,7 +165,8 @@ static void gtk_color_selection_show_all (GtkWidget *widget static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel, gint index, GdkColor *color); -static GdkGC *get_focus_gc (GtkWidget *drawing_area, +static void set_focus_line_attributes (GtkWidget *drawing_area, + cairo_t *cr, gint *focus_width); static void default_noscreen_change_palette_func (const GdkColor *colors, gint n_colors); @@ -216,7 +217,7 @@ static const guchar dropper_mask[] = { #define SAMPLE_HEIGHT 28 static void color_sample_draw_sample (GtkColorSelection *colorsel, int which); -static void color_sample_draw_samples (GtkColorSelection *colorsel); +static void color_sample_update_samples (GtkColorSelection *colorsel); static void set_color_internal (GtkColorSelection *colorsel, @@ -377,11 +378,9 @@ static void color_sample_draw_sample (GtkColorSelection *colorsel, int which) { GtkWidget *da; - gint x, y, i, wid, heig, f, n, goff; - guchar c[3 * 2], cc[3 * 4], *cp = c; - gdouble o; - guchar *buf; + gint x, y, wid, heig, goff; ColorSelectionPrivate *priv; + cairo_t *cr; g_return_if_fail (colorsel != NULL); priv = colorsel->private_data; @@ -389,81 +388,74 @@ color_sample_draw_sample (GtkColorSelection *colorsel, int which) g_return_if_fail (priv->sample_area != NULL); if (!GTK_WIDGET_DRAWABLE (priv->sample_area)) return; - + if (which == 0) { da = priv->old_sample; - for (n = 0, i = COLORSEL_RED; n < 3; n++, i++) - c[n] = (guchar) (UNSCALE (priv->old_color[i]) >> 8); goff = 0; } else { da = priv->cur_sample; - for (n = 0, i = COLORSEL_RED; n < 3; n++, i++) - c[n] = (guchar) (UNSCALE (priv->color[i]) >> 8); goff = priv->old_sample->allocation.width % 32; } + + cr = gdk_drawable_create_cairo_context (da->window); wid = da->allocation.width; heig = da->allocation.height; + + /* Below needs tweaking for non-power-of-two */ +#define CHECK_SIZE 16 - buf = g_new (guchar, 3 * wid * heig); - -#if 0 - i = COLORSEL_RED; - for (n = 0; n < 3; n++) + if (priv->has_opacity) { - c[n] = (guchar) (255.0 * priv->old_color[i]); - c[n + 3] = (guchar) (255.0 * priv->color[i++]); + /* Draw checks in background */ + + cairo_set_rgb_color (cr, 0.5, 0.5, 0.5); + cairo_rectangle (cr, 0, 0, wid, heig); + cairo_fill (cr); + + cairo_set_rgb_color (cr, 0.75, 0.75, 0.75); + for (x = goff & -CHECK_SIZE; x < goff + wid; x += CHECK_SIZE) + for (y = 0; y < heig; y += CHECK_SIZE) + if ((x / CHECK_SIZE + y / CHECK_SIZE) % 2 == 0) + cairo_rectangle (cr, x - goff, y, CHECK_SIZE, CHECK_SIZE); + cairo_fill (cr); } -#endif - - if (priv->has_opacity) + + if (which == 0) { - o = (which) ? priv->color[COLORSEL_OPACITY] : priv->old_color[COLORSEL_OPACITY]; - - for (n = 0; n < 3; n++) - { - cc[n] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n])); - cc[n + 3] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n])); - } - cp = cc; + cairo_set_rgb_color (cr, + priv->old_color[COLORSEL_RED], + priv->old_color[COLORSEL_GREEN], + priv->old_color[COLORSEL_BLUE]); + if (priv->has_opacity) + cairo_set_alpha (cr, priv->old_color[COLORSEL_OPACITY]); } - - i = 0; - for (y = 0; y < heig; y++) + else { - for (x = 0; x < wid; x++) - { - if (priv->has_opacity) - f = 3 * ((((goff + x) % 32) < 16) ^ ((y % 32) < 16)); - else - f = 0; - - for (n = 0; n < 3; n++) - buf[i++] = cp[n + f]; - } + cairo_set_rgb_color (cr, + priv->color[COLORSEL_RED], + priv->color[COLORSEL_GREEN], + priv->color[COLORSEL_BLUE]); + if (priv->has_opacity) + cairo_set_alpha (cr, priv->color[COLORSEL_OPACITY]); } - - gdk_draw_rgb_image (da->window, - da->style->black_gc, - 0, 0, - wid, heig, - GDK_RGB_DITHER_NORMAL, - buf, - 3*wid); - - - g_free (buf); + + cairo_rectangle (cr, 0, 0, wid, heig); + cairo_fill (cr); + + cairo_destroy (cr); } static void -color_sample_draw_samples (GtkColorSelection *colorsel) +color_sample_update_samples (GtkColorSelection *colorsel) { - color_sample_draw_sample (colorsel, 0); - color_sample_draw_sample (colorsel, 1); + ColorSelectionPrivate *priv = colorsel->private_data; + gtk_widget_queue_draw (priv->old_sample); + gtk_widget_queue_draw (priv->cur_sample); } static gboolean @@ -614,31 +606,42 @@ palette_paint (GtkWidget *drawing_area, GdkRectangle *area, gpointer data) { + cairo_t *cr; + gint focus_width; + if (drawing_area->window == NULL) return; - gdk_draw_rectangle (drawing_area->window, - drawing_area->style->bg_gc[GTK_STATE_NORMAL], - TRUE, - area->x, area->y, area->width, area->height); + cr = gdk_drawable_create_cairo_context (drawing_area->window); + + gdk_cairo_set_source_color (cr, &drawing_area->style->bg[GTK_STATE_NORMAL]); + cairo_rectangle (cr, + area->x, area->y, area->width, area->height); + cairo_fill (cr); if (GTK_WIDGET_HAS_FOCUS (drawing_area)) { - gint focus_width; - GdkGC *gc = get_focus_gc (drawing_area, &focus_width); - gdk_draw_rectangle (drawing_area->window, - gc, FALSE, focus_width / 2, focus_width / 2, - drawing_area->allocation.width - focus_width, - drawing_area->allocation.height - focus_width); - g_object_unref (gc); + set_focus_line_attributes (drawing_area, cr, &focus_width); + g_print ("%g %g %g %g\n", + focus_width / 2., focus_width / 2., + (double)drawing_area->allocation.width - focus_width, + (double)drawing_area->allocation.height - focus_width); + + cairo_rectangle (cr, + focus_width / 2., focus_width / 2., + drawing_area->allocation.width - focus_width, + drawing_area->allocation.height - focus_width); + cairo_stroke (cr); } + + cairo_destroy (cr); } -static GdkGC * -get_focus_gc (GtkWidget *drawing_area, - gint *focus_width) +static void +set_focus_line_attributes (GtkWidget *drawing_area, + cairo_t *cr, + gint *focus_width) { - GdkGC *gc = gdk_gc_new (drawing_area->window); gdouble color[4]; gint8 *dash_list; @@ -648,22 +651,42 @@ get_focus_gc (GtkWidget *drawing_area, NULL); palette_get_color (drawing_area, color); - + if (INTENSITY (color[0], color[1], color[2]) > 0.5) - gdk_gc_copy (gc, drawing_area->style->black_gc); + cairo_set_rgb_color (cr, 0., 0., 0.); else - gdk_gc_copy (gc, drawing_area->style->white_gc); + cairo_set_rgb_color (cr, 1., 1., 1.); - gdk_gc_set_line_attributes (gc, *focus_width, - dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID, - GDK_CAP_BUTT, GDK_JOIN_MITER); + cairo_set_line_width (cr, *focus_width); if (dash_list[0]) - gdk_gc_set_dashes (gc, 0, dash_list, strlen ((char *)dash_list)); + { + gint n_dashes = strlen (dash_list); + gdouble *dashes = g_new (gdouble, n_dashes); + gdouble total_length = 0; + gdouble dash_offset; + gint i; + + for (i = 0; i < n_dashes; i++) + { + dashes[i] = dash_list[i]; + total_length += dash_list[i]; + } + + /* The dash offset here aligns the pattern to integer pixels + * by starting the dash at the right side of the left border + * Negative dash offsets in cairo don't work + * (https://bugs.freedesktop.org/show_bug.cgi?id=2729) + */ + dash_offset = - *focus_width / 2.; + while (dash_offset < 0) + dash_offset += total_length; + + cairo_set_dash (cr, dashes, n_dashes, dash_offset); + g_free (dashes); + } g_free (dash_list); - - return gc; } static void @@ -1649,7 +1672,7 @@ update_color (GtkColorSelection *colorsel) gchar *ptr; priv->changing = TRUE; - color_sample_draw_samples (colorsel); + color_sample_update_samples (colorsel); gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel), priv->color[COLORSEL_HUE], @@ -2208,7 +2231,7 @@ gtk_color_selection_set_has_opacity_control (GtkColorSelection *colorsel, gtk_widget_hide (priv->opacity_label); gtk_widget_hide (priv->opacity_entry); } - color_sample_draw_samples (colorsel); + color_sample_update_samples (colorsel); g_object_notify (G_OBJECT (colorsel), "has_opacity_control"); } @@ -2448,7 +2471,7 @@ gtk_color_selection_set_previous_color (GtkColorSelection *colorsel, &priv->old_color[COLORSEL_HUE], &priv->old_color[COLORSEL_SATURATION], &priv->old_color[COLORSEL_VALUE]); - color_sample_draw_samples (colorsel); + color_sample_update_samples (colorsel); priv->default_set = TRUE; priv->changing = FALSE; } @@ -2472,7 +2495,7 @@ gtk_color_selection_set_previous_alpha (GtkColorSelection *colorsel, priv = colorsel->private_data; priv->changing = TRUE; priv->old_color[COLORSEL_OPACITY] = SCALE (alpha); - color_sample_draw_samples (colorsel); + color_sample_update_samples (colorsel); priv->default_alpha_set = TRUE; priv->changing = FALSE; } diff --git a/gtk/gtkhruler.c b/gtk/gtkhruler.c index 4f13d80d99..b4997c8957 100644 --- a/gtk/gtkhruler.c +++ b/gtk/gtkhruler.c @@ -135,7 +135,7 @@ static void gtk_hruler_draw_ticks (GtkRuler *ruler) { GtkWidget *widget; - GdkGC *gc, *bg_gc; + cairo_t *cr; gint i; gint width, height; gint xthickness; @@ -159,9 +159,6 @@ gtk_hruler_draw_ticks (GtkRuler *ruler) widget = GTK_WIDGET (ruler); - gc = widget->style->fg_gc[GTK_STATE_NORMAL]; - bg_gc = widget->style->bg_gc[GTK_STATE_NORMAL]; - xthickness = widget->style->xthickness; ythickness = widget->style->ythickness; @@ -179,13 +176,15 @@ gtk_hruler_draw_ticks (GtkRuler *ruler) NULL, widget, "hruler", 0, 0, widget->allocation.width, widget->allocation.height); - - - gdk_draw_line (ruler->backing_store, gc, - xthickness, - height + ythickness, - widget->allocation.width - xthickness, - height + ythickness); + + cr = gdk_drawable_create_cairo_context (ruler->backing_store); + gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); + + cairo_rectangle (cr, + xthickness, + height + ythickness, + widget->allocation.width - 2 * xthickness, + 1); upper = ruler->upper / ruler->metric->pixels_per_unit; lower = ruler->lower / ruler->metric->pixels_per_unit; @@ -242,9 +241,9 @@ gtk_hruler_draw_ticks (GtkRuler *ruler) { pos = ROUND ((cur - lower) * increment); - gdk_draw_line (ruler->backing_store, gc, - pos, height + ythickness, - pos, height - length + ythickness); + cairo_rectangle (cr, + pos, height + ythickness - length, + 1, length); /* draw label */ if (i == 0) @@ -267,15 +266,16 @@ gtk_hruler_draw_ticks (GtkRuler *ruler) } } + cairo_fill (cr); + cairo_destroy (cr); + g_object_unref (layout); } static void gtk_hruler_draw_pos (GtkRuler *ruler) { - GtkWidget *widget; - GdkGC *gc; - int i; + GtkWidget *widget = GTK_WIDGET (ruler); gint x, y; gint width, height; gint bs_width, bs_height; @@ -285,24 +285,23 @@ gtk_hruler_draw_pos (GtkRuler *ruler) if (GTK_WIDGET_DRAWABLE (ruler)) { - widget = GTK_WIDGET (ruler); - - gc = widget->style->fg_gc[GTK_STATE_NORMAL]; xthickness = widget->style->xthickness; ythickness = widget->style->ythickness; width = widget->allocation.width; height = widget->allocation.height - ythickness * 2; - bs_width = height / 2; + bs_width = height / 2 + 2; bs_width |= 1; /* make sure it's odd */ bs_height = bs_width / 2 + 1; if ((bs_width > 0) && (bs_height > 0)) { + cairo_t *cr = gdk_drawable_create_cairo_context (widget->window); + /* If a backing store exists, restore the ruler */ - if (ruler->backing_store && ruler->non_gr_exp_gc) - gdk_draw_drawable (ruler->widget.window, - ruler->non_gr_exp_gc, + if (ruler->backing_store) + gdk_draw_drawable (widget->window, + widget->style->black_gc, ruler->backing_store, ruler->xsrc, ruler->ysrc, ruler->xsrc, ruler->ysrc, @@ -313,11 +312,14 @@ gtk_hruler_draw_pos (GtkRuler *ruler) x = ROUND ((ruler->position - ruler->lower) * increment) + (xthickness - bs_width) / 2 - 1; y = (height + bs_height) / 2 + ythickness; - for (i = 0; i < bs_height; i++) - gdk_draw_line (widget->window, gc, - x + i, y + i, - x + bs_width - 1 - i, y + i); + gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); + + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + bs_width / 2., y + bs_height); + cairo_line_to (cr, x + bs_width, y); + cairo_fill (cr); + cairo_destroy (cr); ruler->xsrc = x; ruler->ysrc = y; diff --git a/gtk/gtkhsv.c b/gtk/gtkhsv.c index cb73ecd8fc..cc8203d660 100644 --- a/gtk/gtkhsv.c +++ b/gtk/gtkhsv.c @@ -917,10 +917,30 @@ gtk_hsv_motion (GtkWidget *widget, /* Redrawing */ +void +set_source_surface (cairo_t *cr, + cairo_surface_t *surface) +{ + cairo_pattern_t *pattern; + cairo_matrix_t *matrix; + double x, y; + + pattern = cairo_pattern_create_for_surface (surface); + + cairo_current_point (cr, &x, &y); + matrix = cairo_matrix_create (); + cairo_matrix_translate (matrix, -x, -y); + cairo_pattern_set_matrix (pattern, matrix); + cairo_matrix_destroy (matrix); + + cairo_set_pattern (cr, pattern); + cairo_pattern_destroy (pattern); +} + /* Paints the hue ring */ static void paint_ring (GtkHSV *hsv, - GdkDrawable *drawable, + cairo_t *cr, gint x, gint y, gint width, @@ -932,13 +952,12 @@ paint_ring (GtkHSV *hsv, gdouble dx, dy, dist; gdouble center; gdouble inner, outer; - guchar *buf, *p; + guint32 *buf, *p; gdouble angle; gdouble hue; gdouble r, g, b; - GdkBitmap *mask; - GdkGC *gc; - GdkColor color; + cairo_surface_t *source; + cairo_t *source_cr; gint focus_width; gint focus_pad; @@ -954,13 +973,13 @@ paint_ring (GtkHSV *hsv, outer = priv->size / 2.0; inner = outer - priv->ring_width; - /* Paint the ring */ + /* Create an image initialized with the ring colors */ - buf = g_new (guchar, width * height * 3); + buf = g_new (guint32, width * height); for (yy = 0; yy < height; yy++) { - p = buf + yy * width * 3; + p = buf + yy * width; dy = -(yy + y - center); @@ -972,8 +991,6 @@ paint_ring (GtkHSV *hsv, if (dist < ((inner-1) * (inner-1)) || dist > ((outer+1) * (outer+1))) { *p++ = 0; - *p++ = 0; - *p++ = 0; continue; } @@ -988,54 +1005,21 @@ paint_ring (GtkHSV *hsv, b = 1.0; hsv_to_rgb (&r, &g, &b); - *p++ = floor (r * 255 + 0.5); - *p++ = floor (g * 255 + 0.5); - *p++ = floor (b * 255 + 0.5); + *p++ = (((int)floor (r * 255 + 0.5) << 16) | + ((int)floor (g * 255 + 0.5) << 8) | + (int)floor (b * 255 + 0.5)); } } - - /* Create clipping mask */ - - mask = gdk_pixmap_new (widget->window, width, height, 1); - gc = gdk_gc_new (mask); - - color.pixel = 0; - gdk_gc_set_foreground (gc, &color); - gdk_draw_rectangle (mask, gc, TRUE, - 0, 0, width, height); - - - color.pixel = 1; - gdk_gc_set_foreground (gc, &color); - gdk_draw_arc (mask, gc, TRUE, - focus_width + focus_pad - x, - focus_width + focus_pad - y, - priv->size - 1, priv->size - 1, - 0, 360 * 64); - - color.pixel = 0; - gdk_gc_set_foreground (gc, &color); - gdk_draw_arc (mask, gc, TRUE, - focus_width + focus_pad - x + priv->ring_width - 1, - focus_width + focus_pad - y + priv->ring_width - 1, - priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1, - 0, 360 * 64); - - g_object_unref (gc); - - gdk_gc_set_clip_mask (priv->gc, mask); - gdk_gc_set_clip_origin (priv->gc, 0, 0); - - /* Draw ring */ - - gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height, - GDK_RGB_DITHER_MAX, - buf, - width * 3, - x, y); - - /* Draw value marker */ + source = cairo_image_surface_create_for_data ((char *)buf, + CAIRO_FORMAT_RGB24, + width, height, 4 * width); + + /* Now draw the value marker onto the source image, so that it + * will get properly clipped at the edges of the ring + */ + source_cr = cairo_create (); + cairo_set_target_surface (source_cr, source); r = priv->h; g = 1.0; @@ -1043,31 +1027,36 @@ paint_ring (GtkHSV *hsv, hsv_to_rgb (&r, &g, &b); if (INTENSITY (r, g, b) > 0.5) - { - color.red = 0x0000; - color.green = 0x0000; - color.blue = 0x0000; - } + cairo_set_rgb_color (source_cr, 0., 0., 0.); else - { - color.red = 0xffff; - color.green = 0xffff; - color.blue = 0xffff; - } + cairo_set_rgb_color (source_cr, 1., 1., 1.); - gdk_gc_set_rgb_fg_color (priv->gc, &color); - - gdk_draw_line (drawable, priv->gc, - -x + center, -y + center, + cairo_move_to (source_cr, -x + center, - y + center); + cairo_line_to (source_cr, -x + center + cos (priv->h * 2.0 * G_PI) * center, -y + center - sin (priv->h * 2.0 * G_PI) * center); + cairo_stroke (source_cr); + cairo_destroy (source_cr); + + /* Draw the ring using the source image */ + + cairo_save (cr); + + cairo_move_to (cr, x, y); + set_source_surface (cr, source); + cairo_surface_destroy (source); + + cairo_set_line_width (cr, priv->ring_width); + cairo_new_path (cr); + cairo_arc (cr, + center, center, + priv->size / 2. - priv->ring_width / 2., + 0, 2 * M_PI); + cairo_stroke (cr); - gdk_gc_set_clip_mask (priv->gc, NULL); - g_object_unref (mask); + cairo_restore (cr); g_free (buf); - - /* Draw ring outline */ } /* Converts an HSV triplet to an integer RGB triplet */ @@ -1092,10 +1081,15 @@ get_color (gdouble h, ? ((a) + ((b) - (a)) * ((i) - (v1)) / ((v2) - (v1))) \ : (a)) +/* Number of pixels we extend out from the edges when creating + * color source to avoid artifacts + */ +#define PAD 3 + /* Paints the HSV triangle */ static void paint_triangle (GtkHSV *hsv, - GdkDrawable *drawable, + cairo_t *cr, gint x, gint y, gint width, @@ -1108,13 +1102,12 @@ paint_triangle (GtkHSV *hsv, gint x2, y2, r2, g2, b2; /* Second vertex */ gint x3, y3, r3, g3, b3; /* Third vertex */ gint t; - guchar *buf, *p; + guint32 *buf, *p; gint xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */ gint xx, yy; - GdkBitmap *mask; - GdkGC *gc; - GdkColor color; - GdkPoint points[3]; + gint x_interp, y_interp; + gint x_start, x_end; + cairo_surface_t *source; gdouble r, g, b; gchar *detail; @@ -1165,42 +1158,37 @@ paint_triangle (GtkHSV *hsv, /* Shade the triangle */ - buf = g_new (guchar, width * height * 3); + buf = g_new (guint32, width * height); for (yy = 0; yy < height; yy++) { - p = buf + yy * width * 3; + p = buf + yy * width; - if (yy + y < y1 || yy + y > y3) - for (xx = 0; xx < width; xx++) - { - *p++ = 0; - *p++ = 0; - *p++ = 0; - } - else { - if (yy + y < y2) + if (yy + y >= y1 - PAD && yy + y < y3 + PAD) { + y_interp = CLAMP (yy + y, y1, y3); + + if (y_interp < y2) { - xl = LERP (x1, x2, y1, y2, yy + y); + xl = LERP (x1, x2, y1, y2, y_interp); - rl = LERP (r1, r2, y1, y2, yy + y); - gl = LERP (g1, g2, y1, y2, yy + y); - bl = LERP (b1, b2, y1, y2, yy + y); + rl = LERP (r1, r2, y1, y2, y_interp); + gl = LERP (g1, g2, y1, y2, y_interp); + bl = LERP (b1, b2, y1, y2, y_interp); } else { - xl = LERP (x2, x3, y2, y3, yy + y); + xl = LERP (x2, x3, y2, y3, y_interp); - rl = LERP (r2, r3, y2, y3, yy + y); - gl = LERP (g2, g3, y2, y3, yy + y); - bl = LERP (b2, b3, y2, y3, yy + y); + rl = LERP (r2, r3, y2, y3, y_interp); + gl = LERP (g2, g3, y2, y3, y_interp); + bl = LERP (b2, b3, y2, y3, y_interp); } - xr = LERP (x1, x3, y1, y3, yy + y); + xr = LERP (x1, x3, y1, y3, y_interp); - rr = LERP (r1, r3, y1, y3, yy + y); - gr = LERP (g1, g3, y1, y3, yy + y); - br = LERP (b1, b3, y1, y3, yy + y); + rr = LERP (r1, r3, y1, y3, y_interp); + gr = LERP (g1, g3, y1, y3, y_interp); + br = LERP (b1, b3, y1, y3, y_interp); if (xl > xr) { @@ -1209,69 +1197,45 @@ paint_triangle (GtkHSV *hsv, SWAP (gl, gr, t); SWAP (bl, br, t); } - - for (xx = 0; xx < width; xx++) + + x_start = MAX (xl - PAD, x); + x_end = MIN (xr + PAD, x + width); + + p += (x_start - x); + + for (xx = x_start; xx < x_end; xx++) { - if (xx + x < xl || xx + x > xr) - { - *p++ = 0; - *p++ = 0; - *p++ = 0; - } - else - { - *p++ = LERP (rl, rr, xl, xr, xx + x); - *p++ = LERP (gl, gr, xl, xr, xx + x); - *p++ = LERP (bl, br, xl, xr, xx + x); - } + x_interp = CLAMP (xx, xl, xr); + + *p++ = ((LERP (rl, rr, xl, xr, x_interp) << 16) | + (LERP (gl, gr, xl, xr, x_interp) << 8) | + LERP (bl, br, xl, xr, x_interp)); } } } - - /* Create clipping mask */ - - mask = gdk_pixmap_new (widget->window, width, height, 1); - gc = gdk_gc_new (mask); - - color.pixel = 0; - gdk_gc_set_foreground (gc, &color); - gdk_draw_rectangle (mask, gc, TRUE, - 0, 0, width, height); + source = cairo_image_surface_create_for_data ((char *)buf, + CAIRO_FORMAT_RGB24, + width, height, 4 * width); - color.pixel = 1; - gdk_gc_set_foreground (gc, &color); - - points[0].x = x1 - x; - points[0].y = y1 - y; - points[1].x = x2 - x; - points[1].y = y2 - y; - points[2].x = x3 - x; - points[2].y = y3 - y; - gdk_draw_polygon (mask, gc, TRUE, points, 3); - - g_object_unref (gc); - - gdk_gc_set_clip_mask (priv->gc, mask); - gdk_gc_set_clip_origin (priv->gc, 0, 0); - - /* Draw triangle */ - - gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height, - GDK_RGB_DITHER_MAX, - buf, - width * 3, - x, y); + /* Draw a triangle with the image as a source */ + + cairo_move_to (cr, x, y); + set_source_surface (cr, source); + cairo_surface_destroy (source); - gdk_gc_set_clip_mask (priv->gc, NULL); - g_object_unref (mask); + cairo_move_to (cr, x1, y1); + cairo_line_to (cr, x2, y2); + cairo_line_to (cr, x3, y3); + cairo_close_path (cr); + cairo_fill (cr); g_free (buf); /* Draw value marker */ - xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5) - x; - yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5) - y; + xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5); + yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5); r = priv->h; g = priv->s; @@ -1281,33 +1245,21 @@ paint_triangle (GtkHSV *hsv, if (INTENSITY (r, g, b) > 0.5) { detail = "colorwheel_light"; - color.red = 0x0000; - color.green = 0x0000; - color.blue = 0x0000; + cairo_set_rgb_color (cr, 0., 0., 0.); } else { detail = "colorwheel_dark"; - color.red = 0xffff; - color.green = 0xffff; - color.blue = 0xffff; + cairo_set_rgb_color (cr, 1., 1., 1.); } - gdk_gc_set_rgb_fg_color (priv->gc, &color); - -#define OUTER_RADIUS 4 -#define INNER_RADIUS 3 +#define RADIUS 4 #define FOCUS_RADIUS 6 - - gdk_draw_arc (drawable, priv->gc, FALSE, - xx - OUTER_RADIUS, yy - OUTER_RADIUS, - OUTER_RADIUS * 2, OUTER_RADIUS * 2, - 0, 360 * 64); - gdk_draw_arc (drawable, priv->gc, FALSE, - xx - INNER_RADIUS, yy - INNER_RADIUS, - INNER_RADIUS * 2, INNER_RADIUS * 2, - 0, 360 * 64); + cairo_new_path (cr); + cairo_arc (cr, xx, yy, RADIUS, 0, 2 * M_PI); + cairo_stroke (cr); + /* Draw focus outline */ if (GTK_WIDGET_HAS_FOCUS (hsv) && @@ -1321,11 +1273,11 @@ paint_triangle (GtkHSV *hsv, "focus-padding", &focus_pad, NULL); - gtk_paint_focus (widget->style, drawable, + gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), NULL, widget, detail, - xx - FOCUS_RADIUS - focus_width - focus_pad, - yy - FOCUS_RADIUS - focus_width - focus_pad, + widget->allocation.x + xx - FOCUS_RADIUS - focus_width - focus_pad, + widget->allocation.y + yy - FOCUS_RADIUS - focus_width - focus_pad, 2 * (FOCUS_RADIUS + focus_width + focus_pad), 2 * (FOCUS_RADIUS + focus_width + focus_pad)); } @@ -1335,14 +1287,14 @@ paint_triangle (GtkHSV *hsv, /* Paints the contents of the HSV color selector */ static void paint (GtkHSV *hsv, - GdkDrawable *drawable, + cairo_t *cr, gint x, gint y, gint width, gint height) { - paint_ring (hsv, drawable, x, y, width, height); - paint_triangle (hsv, drawable, x, y, width, height); + paint_ring (hsv, cr, x, y, width, height); + paint_triangle (hsv, cr, x, y, width, height); } /* Expose_event handler for the HSV color selector */ @@ -1353,14 +1305,14 @@ gtk_hsv_expose (GtkWidget *widget, GtkHSV *hsv; HSVPrivate *priv; GdkRectangle rect, dest; - GdkPixmap *pixmap; + cairo_t *cr; hsv = GTK_HSV (widget); priv = hsv->priv; if (!(GTK_WIDGET_DRAWABLE (widget) && event->window == widget->window)) return FALSE; - + rect.x = widget->allocation.x; rect.y = widget->allocation.y; rect.width = widget->allocation.width; @@ -1369,29 +1321,14 @@ gtk_hsv_expose (GtkWidget *widget, if (!gdk_rectangle_intersect (&event->area, &rect, &dest)) return FALSE; - pixmap = gdk_pixmap_new (widget->window, dest.width, dest.height, - gtk_widget_get_visual (widget)->depth); - - rect = dest; - rect.x = 0; - rect.y = 0; - - gdk_draw_rectangle (pixmap, - widget->style->bg_gc[GTK_WIDGET_STATE (widget)], - TRUE, - 0, 0, dest.width, dest.height); - paint (hsv, pixmap, - dest.x - widget->allocation.x, dest.y - widget->allocation.y, + cr = gdk_drawable_create_cairo_context (widget->window); + + cairo_translate (cr, widget->allocation.x, widget->allocation.y); + paint (hsv, cr, + dest.x - widget->allocation.x, + dest.y - widget->allocation.y, dest.width, dest.height); - gdk_draw_drawable (widget->window, - priv->gc, - pixmap, - 0, 0, - dest.x, - dest.y, - event->area.width, event->area.height); - if (GTK_WIDGET_HAS_FOCUS (hsv) && priv->focus_on_ring) gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), @@ -1401,8 +1338,6 @@ gtk_hsv_expose (GtkWidget *widget, widget->allocation.width, widget->allocation.height); - g_object_unref (pixmap); - return FALSE; } diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index 8fc55ca328..c36301f399 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -202,9 +202,11 @@ static void gtk_icon_view_adjustment_changed (GtkAdjustment *ad GtkIconView *icon_view); static void gtk_icon_view_layout (GtkIconView *icon_view); static void gtk_icon_view_paint_item (GtkIconView *icon_view, + cairo_t *cr, GtkIconViewItem *item, GdkRectangle *area); static void gtk_icon_view_paint_rubberband (GtkIconView *icon_view, + cairo_t *cr, GdkRectangle *area); static void gtk_icon_view_queue_draw_item (GtkIconView *icon_view, GtkIconViewItem *item); @@ -989,12 +991,16 @@ gtk_icon_view_expose (GtkWidget *widget, { GtkIconView *icon_view; GList *icons; + cairo_t *cr; icon_view = GTK_ICON_VIEW (widget); if (expose->window != icon_view->priv->bin_window) return FALSE; + cr = gdk_drawable_create_cairo_context (icon_view->priv->bin_window); + cairo_set_line_width (cr, 1.); + for (icons = icon_view->priv->items; icons; icons = icons->next) { GtkIconViewItem *item = icons->data; GdkRectangle item_rectangle; @@ -1008,23 +1014,21 @@ gtk_icon_view_expose (GtkWidget *widget, continue; #ifdef DEBUG_ICON_VIEW - gdk_draw_rectangle (icon_view->priv->bin_window, - GTK_WIDGET (icon_view)->style->black_gc, - FALSE, - item->x, item->y, - item->width, item->height); - gdk_draw_rectangle (icon_view->priv->bin_window, - GTK_WIDGET (icon_view)->style->black_gc, - FALSE, - item->pixbuf_x, item->pixbuf_y, - item->pixbuf_width, item->pixbuf_height); - gdk_draw_rectangle (icon_view->priv->bin_window, - GTK_WIDGET (icon_view)->style->black_gc, - FALSE, - item->layout_x, item->layout_y, - item->layout_width, item->layout_height); + cairo_rectangle (cr, + item->x + 0.5, item->y + 0.5, + item->width - 1, item->height - 1); + cairo_rectangle (cr, + item->x + 0.5, item->y + 0.5, + item->width - 1, item->height- 1); + cairo_rectangle (cr, + item->pixbuf_x + 0.5, item->pixbuf_y + 0.5, + item->pixbuf_width - 1, item->pixbuf_height- 1); + cairo_rectangle (cr, + item->layout_x + 0.5, item->layout_y + 0.5, + item->layout_width - 1, item->layout_height - 1); + cairo_stroke (cr); #endif - gtk_icon_view_paint_item (icon_view, item, &expose->area); + gtk_icon_view_paint_item (icon_view, cr, item, &expose->area); } @@ -1038,11 +1042,13 @@ gtk_icon_view_expose (GtkWidget *widget, &n_rectangles); while (n_rectangles--) - gtk_icon_view_paint_rubberband (icon_view, &rectangles[n_rectangles]); + gtk_icon_view_paint_rubberband (icon_view, cr, &rectangles[n_rectangles]); g_free (rectangles); } + cairo_destroy (cr); + return TRUE; } @@ -1995,6 +2001,7 @@ create_colorized_pixbuf (GdkPixbuf *src, GdkColor *new_color) static void gtk_icon_view_paint_item (GtkIconView *icon_view, + cairo_t *cr, GtkIconViewItem *item, GdkRectangle *area) { @@ -2027,14 +2034,15 @@ gtk_icon_view_paint_item (GtkIconView *icon_view, } else pixbuf = tmp; + + cairo_move_to (cr, item->pixbuf_x, item->pixbuf_y); + gdk_pixbuf_set_as_cairo_source (pixbuf, cr); + g_object_unref (pixbuf); - gdk_draw_pixbuf (icon_view->priv->bin_window, NULL, pixbuf, - 0, 0, + cairo_rectangle (cr, item->pixbuf_x, item->pixbuf_y, - item->pixbuf_width, item->pixbuf_height, - GDK_RGB_DITHER_NORMAL, item->pixbuf_width, item->pixbuf_height); - g_object_unref (pixbuf); + cairo_fill (cr); } if (icon_view->priv->text_column != -1 || @@ -2042,13 +2050,13 @@ gtk_icon_view_paint_item (GtkIconView *icon_view, { if (item->selected) { - gdk_draw_rectangle (icon_view->priv->bin_window, - GTK_WIDGET (icon_view)->style->base_gc[state], - TRUE, - item->layout_x - ICON_TEXT_PADDING, - item->layout_y - ICON_TEXT_PADDING, - item->layout_width + 2 * ICON_TEXT_PADDING, - item->layout_height + 2 * ICON_TEXT_PADDING); + gdk_cairo_set_source_color (cr, >K_WIDGET (icon_view)->style->base[state]); + cairo_rectangle (cr, + item->layout_x - ICON_TEXT_PADDING, + item->layout_y - ICON_TEXT_PADDING, + item->layout_width + 2 * ICON_TEXT_PADDING, + item->layout_height + 2 * ICON_TEXT_PADDING); + cairo_fill (cr); } gtk_icon_view_update_item_text (icon_view, item); @@ -2077,26 +2085,14 @@ gtk_icon_view_paint_item (GtkIconView *icon_view, } } -static guint32 -gtk_gdk_color_to_rgb (const GdkColor *color) -{ - guint32 result; - result = (0xff0000 | (color->red & 0xff00)); - result <<= 8; - result |= ((color->green & 0xff00) | (color->blue >> 8)); - return result; -} - static void gtk_icon_view_paint_rubberband (GtkIconView *icon_view, + cairo_t *cr, GdkRectangle *area) { GdkRectangle rect; - GdkPixbuf *pixbuf; - GdkGC *gc; GdkRectangle rubber_rect; GdkColor *fill_color_gdk; - guint fill_color; guchar fill_color_alpha; rubber_rect.x = MIN (icon_view->priv->rubberband_x1, icon_view->priv->rubberband_x2); @@ -2112,38 +2108,25 @@ gtk_icon_view_paint_rubberband (GtkIconView *icon_view, "selection_box_alpha", &fill_color_alpha, NULL); - if (!fill_color_gdk) { + if (!fill_color_gdk) fill_color_gdk = gdk_color_copy (>K_WIDGET (icon_view)->style->base[GTK_STATE_SELECTED]); - } - fill_color = gtk_gdk_color_to_rgb (fill_color_gdk) << 8 | fill_color_alpha; + gdk_cairo_set_source_color (cr, fill_color_gdk); + cairo_set_alpha (cr, fill_color_alpha / 255.); - if (!gdk_draw_rectangle_alpha_libgtk_only (icon_view->priv->bin_window, - rect.x, rect.y, rect.width, rect.height, - fill_color_gdk, - fill_color_alpha << 8 | fill_color_alpha)) - { - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, rect.width, rect.height); - gdk_pixbuf_fill (pixbuf, fill_color); - - gdk_draw_pixbuf (icon_view->priv->bin_window, NULL, pixbuf, - 0, 0, - rect.x,rect.y, - rect.width, rect.height, - GDK_RGB_DITHER_NONE, - 0, 0); - g_object_unref (pixbuf); - } + cairo_save (cr); + cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height); + cairo_clip (cr); + cairo_fill (cr); + + cairo_set_alpha (cr, 1.0); + cairo_rectangle (cr, + rubber_rect.x + 0.5, rubber_rect.y + 0.5, + rubber_rect.width - 1, rubber_rect.height - 1); + cairo_stroke (cr); + cairo_restore (cr); - gc = gdk_gc_new (icon_view->priv->bin_window); - gdk_gc_set_rgb_fg_color (gc, fill_color_gdk); - gdk_gc_set_clip_rectangle (gc, &rect); - gdk_draw_rectangle (icon_view->priv->bin_window, - gc, FALSE, - rubber_rect.x, rubber_rect.y, - rubber_rect.width - 1, rubber_rect.height - 1); gdk_color_free (fill_color_gdk); - g_object_unref (gc); } static void diff --git a/gtk/gtkruler.c b/gtk/gtkruler.c index 8f8c02edfc..6c1370104a 100644 --- a/gtk/gtkruler.c +++ b/gtk/gtkruler.c @@ -159,7 +159,6 @@ static void gtk_ruler_init (GtkRuler *ruler) { ruler->backing_store = NULL; - ruler->non_gr_exp_gc = NULL; ruler->xsrc = 0; ruler->ysrc = 0; ruler->slider_size = 0; @@ -391,8 +390,6 @@ gtk_ruler_unrealize (GtkWidget *widget) if (ruler->backing_store) g_object_unref (ruler->backing_store); - if (ruler->non_gr_exp_gc) - g_object_unref (ruler->non_gr_exp_gc); ruler->backing_store = NULL; ruler->non_gr_exp_gc = NULL; diff --git a/gtk/gtkruler.h b/gtk/gtkruler.h index a27c698663..e0512ecb8b 100644 --- a/gtk/gtkruler.h +++ b/gtk/gtkruler.h @@ -67,7 +67,7 @@ struct _GtkRuler GtkWidget widget; GdkPixmap *backing_store; - GdkGC *non_gr_exp_gc; + GdkGC *non_gr_exp_gc; /* unused */ GtkRulerMetric *metric; gint xsrc, ysrc; gint slider_size; diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index f74f5cc265..badf30abd1 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -45,7 +45,7 @@ struct _GtkSettingsPropertyValue GtkSettingsSource source; }; -#ifdef GDK_WINDOWING_X11 +#if 0 #include <pango/pangoxft.h> #include <gdk/x11/gdkx.h> #endif @@ -133,7 +133,7 @@ gtk_settings_get_type (void) return settings_type; } -#ifdef GDK_WINDOWING_X11 +#if 0 static void gtk_default_substitute (FcPattern *pattern, gpointer data) @@ -478,7 +478,7 @@ gtk_settings_get_for_screen (GdkScreen *screen) settings->screen = screen; g_object_set_data (G_OBJECT (screen), "gtk-settings", settings); -#ifdef GDK_WINDOWING_X11 +#if 0 /* Set the default substitution function for the Pango fontmap. */ pango_xft_set_default_substitute (GDK_SCREEN_XDISPLAY (screen), @@ -615,7 +615,7 @@ gtk_settings_notify (GObject *object, case PROP_DOUBLE_CLICK_DISTANCE: settings_update_double_click (settings); break; -#ifdef GDK_WINDOWING_X11 +#if 0 case PROP_XFT_ANTIALIAS: case PROP_XFT_HINTING: case PROP_XFT_HINTSTYLE: diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c index c641b1f85a..8f9adc4d3a 100644 --- a/gtk/gtkstyle.c +++ b/gtk/gtkstyle.c @@ -325,128 +325,6 @@ static GdkFont *gtk_style_get_font_internal (GtkStyle *style); static const GtkRequisition default_option_indicator_size = { 7, 13 }; static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 }; -#define INDICATOR_PART_SIZE 13 - -typedef enum { - CHECK_AA, - CHECK_BASE, - CHECK_BLACK, - CHECK_DARK, - CHECK_LIGHT, - CHECK_MID, - CHECK_TEXT, - CHECK_INCONSISTENT_TEXT, - RADIO_BASE, - RADIO_BLACK, - RADIO_DARK, - RADIO_LIGHT, - RADIO_MID, - RADIO_TEXT, - RADIO_INCONSISTENT_AA, - RADIO_INCONSISTENT_TEXT -} IndicatorPart; - -/* - * Extracted from check-13.png, width=13, height=13 - */ -static const guchar check_black_bits[] = { - 0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02, - 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00}; -static const guchar check_dark_bits[] = { - 0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01, - 0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00}; -static const guchar check_mid_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00, - 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00,0x00,0x00}; -static const guchar check_light_bits[] = { - 0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00, - 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f,0x00,0x00}; -static const guchar check_text_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0x80,0x00,0x58, - 0x00,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -static const guchar check_aa_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x58,0x00,0xa0, - 0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -static const guchar check_base_bits[] = { - 0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc, - 0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00,0x00,0x00}; - -/* - * Extracted from check-13-inconsistent.png, width=13, height=13 - */ -static const guchar check_inconsistent_text_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0xf8, - 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -#if 0 -/* - * check_inconsistent_aa_bits is currently not used, since it is all zeros. - */ -static const guchar check_inconsistent_aa_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -#endif - -/* - * Extracted from radio-13.png, width=13, height=13 - */ -static const guchar radio_black_bits[] = { - 0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02, - 0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x08}; -static const guchar radio_dark_bits[] = { - 0xf0,0x00,0x0c,0x02,0x02,0x04,0x02,0x04,0x01,0x08,0x01,0x08,0x01,0x08,0x01, - 0x08,0x00,0x08,0x02,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00,0x00,0x00}; -static const guchar radio_mid_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -static const guchar radio_light_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00, - 0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x06,0xe0,0x01,0x00,0x00}; -static const guchar radio_text_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0, - 0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -#if 0 -/* - * radio_aa_bits is currently not used, since it is all zeros. - */ -static const guchar radio_aa_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -#endif -static const guchar radio_base_bits[] = { - 0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc, - 0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00,0x00,0x00}; - -/* - * Extracted from radio-13.png, width=13, height=13 - */ -static const guchar radio_inconsistent_text_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -static const guchar radio_inconsistent_aa_bits[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,0x00,0xf8, - 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - -static struct { - const guchar *bits; - GList *bmap_list; /* list of GdkBitmap */ -} indicator_parts[] = { - { check_aa_bits, NULL }, - { check_base_bits, NULL }, - { check_black_bits, NULL }, - { check_dark_bits, NULL }, - { check_light_bits, NULL }, - { check_mid_bits, NULL }, - { check_text_bits, NULL }, - { check_inconsistent_text_bits, NULL }, - { radio_base_bits, NULL }, - { radio_black_bits, NULL }, - { radio_dark_bits, NULL }, - { radio_light_bits, NULL }, - { radio_mid_bits, NULL }, - { radio_text_bits, NULL }, - { radio_inconsistent_aa_bits, NULL }, - { radio_inconsistent_text_bits, NULL }, -}; #define GTK_GRAY 0xdcdc, 0xdada, 0xd5d5 #define GTK_DARK_GRAY 0xc4c4, 0xc2c2, 0xbdbd #define GTK_LIGHT_GRAY 0xeeee, 0xebeb, 0xe7e7 @@ -2263,57 +2141,6 @@ sanitize_size (GdkWindow *window, gdk_drawable_get_size (window, NULL, height); } -static GdkBitmap * -get_indicator_for_screen (GdkDrawable *drawable, - IndicatorPart part) - -{ - GdkScreen *screen = gdk_drawable_get_screen (drawable); - GdkBitmap *bitmap; - GList *tmp_list; - - tmp_list = indicator_parts[part].bmap_list; - while (tmp_list) - { - bitmap = tmp_list->data; - - if (gdk_drawable_get_screen (bitmap) == screen) - return bitmap; - - tmp_list = tmp_list->next; - } - - bitmap = gdk_bitmap_create_from_data (drawable, - (gchar *)indicator_parts[part].bits, - INDICATOR_PART_SIZE, INDICATOR_PART_SIZE); - indicator_parts[part].bmap_list = g_list_prepend (indicator_parts[part].bmap_list, bitmap); - - return bitmap; -} - -static void -draw_part (GdkDrawable *drawable, - GdkGC *gc, - GdkRectangle *area, - gint x, - gint y, - IndicatorPart part) -{ - if (area) - gdk_gc_set_clip_rectangle (gc, area); - - gdk_gc_set_ts_origin (gc, x, y); - gdk_gc_set_stipple (gc, get_indicator_for_screen (drawable, part)); - gdk_gc_set_fill (gc, GDK_STIPPLED); - - gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE); - - gdk_gc_set_fill (gc, GDK_SOLID); - - if (area) - gdk_gc_set_clip_rectangle (gc, NULL); -} - static void gtk_default_draw_hline (GtkStyle *style, GdkWindow *window, @@ -3065,7 +2892,7 @@ gtk_default_draw_polygon (GtkStyle *style, static void draw_arrow (GdkWindow *window, - GdkGC *gc, + GdkColor *color, GdkRectangle *area, GtkArrowType arrow_type, gint x, @@ -3073,34 +2900,49 @@ draw_arrow (GdkWindow *window, gint width, gint height) { - gint i, j; - + cairo_t *cr = gdk_drawable_create_cairo_context (window); + gdk_cairo_set_source_color (cr, color); + if (area) - gdk_gc_set_clip_rectangle (gc, area); - + { + cairo_save (cr); + cairo_rectangle (cr, area->x, area->y, area->width, area->height); + cairo_clip (cr); + cairo_new_path (cr); + } + if (arrow_type == GTK_ARROW_DOWN) { - for (i = 0, j = 0; i < height; i++, j++) - gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i); + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + width, y); + cairo_line_to (cr, x + width / 2., y + height); } else if (arrow_type == GTK_ARROW_UP) { - for (i = height - 1, j = 0; i >= 0; i--, j++) - gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i); + cairo_move_to (cr, x, y + height); + cairo_line_to (cr, x + width / 2., y); + cairo_line_to (cr, x + width, y + height); } else if (arrow_type == GTK_ARROW_LEFT) { - for (i = width - 1, j = 0; i >= 0; i--, j++) - gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1); + cairo_move_to (cr, x + width, y); + cairo_line_to (cr, x + width, y + height); + cairo_line_to (cr, x, y + height / 2.); } else if (arrow_type == GTK_ARROW_RIGHT) { - for (i = 0, j = 0; i < width; i++, j++) - gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1); + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + width, y + height / 2.); + cairo_line_to (cr, x, y + height); } + cairo_close_path (cr); + cairo_fill (cr); + if (area) - gdk_gc_set_clip_rectangle (gc, NULL); + cairo_restore (cr); + + cairo_destroy (cr); } static void @@ -3200,9 +3042,9 @@ gtk_default_draw_arrow (GtkStyle *style, y++; if (state == GTK_STATE_INSENSITIVE) - draw_arrow (window, style->white_gc, area, arrow_type, + draw_arrow (window, &style->white, area, arrow_type, x + 1, y + 1, width, height); - draw_arrow (window, style->fg_gc[state], area, arrow_type, + draw_arrow (window, &style->fg[state], area, arrow_type, x, y, width, height); } @@ -3760,21 +3602,6 @@ gtk_default_draw_flat_box (GtkStyle *style, g_object_unref (freeme); } -static GdkGC * -create_aa_gc (GdkWindow *window, GtkStyle *style, GtkStateType state_type) -{ - GdkColor aa_color; - GdkGC *gc = gdk_gc_new (window); - - aa_color.red = (style->fg[state_type].red + style->bg[state_type].red) / 2; - aa_color.green = (style->fg[state_type].green + style->bg[state_type].green) / 2; - aa_color.blue = (style->fg[state_type].blue + style->bg[state_type].blue) / 2; - - gdk_gc_set_rgb_fg_color (gc, &aa_color); - - return gc; -} - static void gtk_default_draw_check (GtkStyle *style, GdkWindow *window, @@ -3788,92 +3615,121 @@ gtk_default_draw_check (GtkStyle *style, gint width, gint height) { - if (detail && strcmp (detail, "cellcheck") == 0) - { - if (area) - gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], area); - gdk_draw_rectangle (window, - widget->style->base_gc[state_type], - TRUE, - x, y, - width, height); - if (area) - { - gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], NULL); - gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], area); - } - gdk_draw_rectangle (window, - widget->style->text_gc[state_type], - FALSE, - x, y, - width, height); - if (area) - gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], NULL); - - x -= (1 + INDICATOR_PART_SIZE - width) / 2; - y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1); - if (shadow_type == GTK_SHADOW_IN) - { - draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT); - draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA); - } - else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ - { - draw_part (window, style->text_gc[state_type], area, x, y, CHECK_INCONSISTENT_TEXT); - } - } - else + cairo_t *cr = gdk_drawable_create_cairo_context (window); + enum { BUTTON, MENU, CELL } type = BUTTON; + int exterior_size; + int interior_size; + int pad; + + if (detail) { - GdkGC *free_me = NULL; + if (strcmp (detail, "cellcheck") == 0) + type = CELL; + else if (strcmp (detail, "check") == 0) + type = MENU; + } - GdkGC *base_gc; - GdkGC *text_gc; - GdkGC *aa_gc; + if (area) + { + cairo_save (cr); + cairo_rectangle (cr, area->x, area->y, area->width, area->height); + cairo_clip (cr); + cairo_new_path (cr); + } + + exterior_size = MIN (width, height); + if (exterior_size % 2 == 0) /* Ensure odd */ + exterior_size -= -1; - x -= (1 + INDICATOR_PART_SIZE - width) / 2; - y -= (1 + INDICATOR_PART_SIZE - height) / 2; + pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9); + interior_size = MAX (1, exterior_size - 2 * pad); - if (detail && strcmp (detail, "check") == 0) /* Menu item */ - { - text_gc = style->fg_gc[state_type]; - base_gc = style->bg_gc[state_type]; - aa_gc = free_me = create_aa_gc (window, style, state_type); - } + if (interior_size < 7) + { + interior_size = 7; + pad = MAX (0, (exterior_size - interior_size) / 2); + } + + x -= (1 + exterior_size - width) / 2; + y -= (1 + exterior_size - height) / 2; + + switch (type) + { + case BUTTON: + case CELL: + if (type == BUTTON) + gdk_cairo_set_source_color (cr, &style->fg[state_type]); else - { - if (state_type == GTK_STATE_ACTIVE) - { - text_gc = style->fg_gc[state_type]; - base_gc = style->bg_gc[state_type]; - aa_gc = free_me = create_aa_gc (window, style, state_type); - } - else - { - text_gc = style->text_gc[state_type]; - base_gc = style->base_gc[state_type]; - aa_gc = style->text_aa_gc[state_type]; - } + gdk_cairo_set_source_color (cr, &style->text[state_type]); + + cairo_set_line_width (cr, 1.0); + cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1); + cairo_stroke (cr); - draw_part (window, base_gc, area, x, y, CHECK_BASE); - draw_part (window, style->black_gc, area, x, y, CHECK_BLACK); - draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK); - draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID); - draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT); - } + gdk_cairo_set_source_color (cr, &style->base[state_type]); + cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2); + cairo_fill (cr); + break; - if (shadow_type == GTK_SHADOW_IN) - { - draw_part (window, text_gc, area, x, y, CHECK_TEXT); - draw_part (window, aa_gc, area, x, y, CHECK_AA); - } - else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ - { - draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT); - } + case MENU: + break; + } + + switch (type) + { + case BUTTON: + case CELL: + gdk_cairo_set_source_color (cr, &style->text[state_type]); + break; + case MENU: + gdk_cairo_set_source_color (cr, &style->fg[state_type]); + break; + } - if (free_me) - g_object_unref (free_me); + if (shadow_type == GTK_SHADOW_IN) + { + cairo_translate (cr, + x + pad, y + pad); + + cairo_scale (cr, interior_size / 7., interior_size / 7.); + + cairo_move_to (cr, 7.0, 0.0); + cairo_line_to (cr, 7.5, 1.0); + cairo_curve_to (cr, 5.3, 2.0, + 4.3, 4.0, + 3.5, 7.0); + cairo_curve_to (cr, 3.0, 5.7, + 1.3, 4.7, + 0.0, 4.7); + cairo_line_to (cr, 0.2, 3.5); + cairo_curve_to (cr, 1.1, 3.5, + 2.3, 4.3, + 3.0, 5.0); + cairo_curve_to (cr, 1.0, 3.9, + 2.4, 4.1, + 3.2, 4.9); + cairo_curve_to (cr, 3.5, 3.1, + 5.2, 2.0, + 7.0, 0.0); + + cairo_fill (cr); } + else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ + { + int line_thickness = MAX (1, (3 + interior_size * 2) / 7); + + cairo_rectangle (cr, + x + pad, + y + pad + (1 + interior_size - line_thickness) / 2, + interior_size, + line_thickness); + cairo_fill (cr); + } + + if (area) + cairo_restore (cr); + + cairo_destroy (cr); } static void @@ -3889,96 +3745,118 @@ gtk_default_draw_option (GtkStyle *style, gint width, gint height) { - if (detail && strcmp (detail, "cellradio") == 0) - { - if (area) - gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], area); - gdk_draw_arc (window, - widget->style->fg_gc[state_type], - FALSE, - x, y, - width, - height, - 0, 360*64); - - if (shadow_type == GTK_SHADOW_IN) - { - gdk_draw_arc (window, - widget->style->fg_gc[state_type], - TRUE, - x + 2, - y + 2, - width - 4, - height - 4, - 0, 360*64); - } - else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ - { - draw_part (window, widget->style->fg_gc[state_type], - area, x, y, CHECK_INCONSISTENT_TEXT); - } - if (area) - gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], NULL); + cairo_t *cr = gdk_drawable_create_cairo_context (window); + enum { BUTTON, MENU, CELL } type = BUTTON; + int exterior_size; + + if (detail) + { + if (strcmp (detail, "radio") == 0) + type = CELL; + else if (strcmp (detail, "option") == 0) + type = MENU; } - else + + if (area) + { + cairo_save (cr); + cairo_rectangle (cr, area->x, area->y, area->width, area->height); + cairo_clip (cr); + cairo_new_path (cr); + } + + exterior_size = MIN (width, height); + if (exterior_size % 2 == 0) /* Ensure odd */ + exterior_size -= -1; + + x -= (1 + exterior_size - width) / 2; + y -= (1 + exterior_size - height) / 2; + + switch (type) { - GdkGC *free_me = NULL; + case BUTTON: + case CELL: + gdk_cairo_set_source_color (cr, &style->base[state_type]); - GdkGC *base_gc; - GdkGC *text_gc; - GdkGC *aa_gc; + cairo_arc (cr, + x + exterior_size / 2., + y + exterior_size / 2., + (exterior_size - 1) / 2., + 0, 2 * M_PI); + + cairo_save (cr); + cairo_fill (cr); + cairo_restore (cr); + + if (type == BUTTON) + gdk_cairo_set_source_color (cr, &style->fg[state_type]); + else + gdk_cairo_set_source_color (cr, &style->text[state_type]); + + cairo_set_line_width (cr, 1.); + cairo_stroke (cr); + break; - x -= (1 + INDICATOR_PART_SIZE - width) / 2; - y -= (1 + INDICATOR_PART_SIZE - height) / 2; + case MENU: + break; + } + + switch (type) + { + case BUTTON: + gdk_cairo_set_source_color (cr, &style->text[state_type]); + break; + case CELL: + break; + case MENU: + gdk_cairo_set_source_color (cr, &style->fg[state_type]); + break; + } - if (detail && strcmp (detail, "option") == 0) /* Menu item */ + if (shadow_type == GTK_SHADOW_IN) + { + int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9); + int interior_size = MAX (1, exterior_size - 2 * pad); + + if (interior_size < 5) { - text_gc = style->fg_gc[state_type]; - base_gc = style->bg_gc[state_type]; - aa_gc = free_me = create_aa_gc (window, style, state_type); + interior_size = 7; + pad = MAX (0, (exterior_size - interior_size) / 2); } - else - { - if (state_type == GTK_STATE_ACTIVE) - { - text_gc = style->fg_gc[state_type]; - base_gc = style->bg_gc[state_type]; - aa_gc = free_me = create_aa_gc (window, style, state_type); - } - else - { - text_gc = style->text_gc[state_type]; - base_gc = style->base_gc[state_type]; - aa_gc = style->text_aa_gc[state_type]; - } - draw_part (window, base_gc, area, x, y, RADIO_BASE); - draw_part (window, style->black_gc, area, x, y, RADIO_BLACK); - draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK); - draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID); - draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT); - } + cairo_arc (cr, + x + pad + interior_size / 2., + y + pad + interior_size / 2., + interior_size / 2., + 0, 2 * M_PI); + cairo_fill (cr); + } + else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ + { + int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9); + int interior_size = MAX (1, exterior_size - 2 * pad); + int line_thickness; - if (shadow_type == GTK_SHADOW_IN) + if (interior_size < 7) { - draw_part (window, text_gc, area, x, y, RADIO_TEXT); - } - else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ - { - if (detail && strcmp (detail, "option") == 0) /* Menu item */ - { - draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT); - } - else - { - draw_part (window, text_gc, area, x, y, RADIO_INCONSISTENT_TEXT); - draw_part (window, aa_gc, area, x, y, RADIO_INCONSISTENT_AA); - } + interior_size = 7; + pad = MAX (0, (exterior_size - interior_size) / 2); } - if (free_me) - g_object_unref (free_me); + line_thickness = MAX (1, (3 + interior_size * 2) / 7); + + cairo_rectangle (cr, + x + pad, + y + pad + (interior_size - line_thickness) / 2., + interior_size, + line_thickness); + cairo_fill (cr); } + + if (area) + cairo_restore (cr); + + cairo_destroy (cr); } static void @@ -4010,21 +3888,21 @@ gtk_default_draw_tab (GtkStyle *style, if (state_type == GTK_STATE_INSENSITIVE) { - draw_arrow (window, style->white_gc, area, + draw_arrow (window, &style->white, area, GTK_ARROW_UP, x + 1, y + 1, indicator_size.width, arrow_height); - draw_arrow (window, style->white_gc, area, + draw_arrow (window, &style->white, area, GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1, indicator_size.width, arrow_height); } - draw_arrow (window, style->fg_gc[state_type], area, + draw_arrow (window, &style->fg[state_type], area, GTK_ARROW_UP, x, y, indicator_size.width, arrow_height); - draw_arrow (window, style->fg_gc[state_type], area, + draw_arrow (window, &style->fg[state_type], area, GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE, indicator_size.width, arrow_height); } @@ -4653,12 +4531,10 @@ gtk_default_draw_focus (GtkStyle *style, gint width, gint height) { - GdkPoint points[5]; - GdkGC *gc; + cairo_t *cr; gboolean free_dash_list = FALSE; gint line_width = 1; gint8 *dash_list = "\1\1"; - gint dash_len; if (widget) { @@ -4670,22 +4546,6 @@ gtk_default_draw_focus (GtkStyle *style, free_dash_list = TRUE; } - sanitize_size (window, &width, &height); - - if (detail && !strcmp (detail, "colorwheel_light")) - gc = style->black_gc; - else if (detail && !strcmp (detail, "colorwheel_dark")) - gc = style->white_gc; - else - gc = style->fg_gc[state_type]; - - gdk_gc_set_line_attributes (gc, line_width, - dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID, - GDK_CAP_BUTT, GDK_JOIN_MITER); - - if (area) - gdk_gc_set_clip_rectangle (gc, area); - if (detail && !strcmp (detail, "add-mode")) { if (free_dash_list) @@ -4695,88 +4555,61 @@ gtk_default_draw_focus (GtkStyle *style, free_dash_list = FALSE; } - points[0].x = x + line_width / 2; - points[0].y = y + line_width / 2; - points[1].x = x + width - line_width + line_width / 2; - points[1].y = y + line_width / 2; - points[2].x = x + width - line_width + line_width / 2; - points[2].y = y + height - line_width + line_width / 2; - points[3].x = x + line_width / 2; - points[3].y = y + height - line_width + line_width / 2; - points[4] = points[0]; + sanitize_size (window, &width, &height); - if (!dash_list[0]) - { - gdk_draw_lines (window, gc, points, 5); - } + cr = gdk_drawable_create_cairo_context (window); + + if (detail && !strcmp (detail, "colorwheel_light")) + cairo_set_rgb_color (cr, 0., 0., 0.); + else if (detail && !strcmp (detail, "colorwheel_dark")) + cairo_set_rgb_color (cr, 1., 1., 1.); else + gdk_cairo_set_source_color (cr, &style->fg[state_type]); + + cairo_set_line_width (cr, line_width); + + if (dash_list[0]) { - /* We go through all the pain below because the X rasterization - * rules don't really work right for dashed lines if you - * want continuity in segments that go between top/right - * and left/bottom. For instance, a top left corner - * with a 1-1 dash is drawn as: - * - * X X X - * X - * - * X - * - * This is because pixels on the top and left boundaries - * of polygons are drawn, but not on the bottom and right. - * So, if you have a line going up that turns the corner - * and goes right, there is a one pixel shift in the pattern. - * - * So, to fix this, we drawn the top and right in one call, - * then the left and bottom in another call, fixing up - * the dash offset for the second call ourselves to get - * continuity at the upper left. - * - * It's not perfect since we really should have a join at - * the upper left and lower right instead of two intersecting - * lines but that's only really apparent for no-dashes, - * which (for this reason) are done as one polygon and - * don't to through this code path. - */ - - dash_len = strlen (dash_list); - - if (dash_list[0]) - gdk_gc_set_dashes (gc, 0, dash_list, dash_len); - - gdk_draw_lines (window, gc, points, 3); - - /* We draw this line one farther over than it is "supposed" to - * because of another rasterization problem ... if two 1 pixel - * unjoined lines meet at the lower right, there will be a missing - * pixel. - */ - points[2].x += 1; - - if (dash_list[0]) + gint n_dashes = strlen (dash_list); + gdouble *dashes = g_new (gdouble, n_dashes); + gdouble total_length = 0; + gdouble dash_offset; + gint i; + + for (i = 0; i < n_dashes; i++) { - gint dash_pixels = 0; - gint i; - - /* Adjust the dash offset for the bottom and left so we - * match up at the upper left. - */ - for (i = 0; i < dash_len; i++) - dash_pixels += dash_list[i]; - - if (dash_len % 2 == 1) - dash_pixels *= 2; - - gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len); + dashes[i] = dash_list[i]; + total_length += dash_list[i]; } + + /* The dash offset here aligns the pattern to integer pixels + * by starting the dash at the right side of the left border + * Negative dash offsets in cairo don't work + * (https://bugs.freedesktop.org/show_bug.cgi?id=2729) + */ + dash_offset = - line_width / 2.; + while (dash_offset < 0) + dash_offset += total_length; - gdk_draw_lines (window, gc, points + 2, 3); + cairo_set_dash (cr, dashes, n_dashes, dash_offset); + g_free (dashes); } - gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); - if (area) - gdk_gc_set_clip_rectangle (gc, NULL); + { + cairo_rectangle (cr, + area->x, area->y, area->width, area->height); + cairo_clip (cr); + cairo_new_path (cr); + } + + cairo_rectangle (cr, + x + line_width / 2., + y + line_width / 2., + width - line_width, + height - line_width); + cairo_stroke (cr); + cairo_destroy (cr); if (free_dash_list) g_free (dash_list); diff --git a/gtk/gtkvruler.c b/gtk/gtkvruler.c index 996092041e..f967df5b40 100644 --- a/gtk/gtkvruler.c +++ b/gtk/gtkvruler.c @@ -136,7 +136,7 @@ static void gtk_vruler_draw_ticks (GtkRuler *ruler) { GtkWidget *widget; - GdkGC *gc, *bg_gc; + cairo_t *cr; gint i, j; gint width, height; gint xthickness; @@ -160,9 +160,6 @@ gtk_vruler_draw_ticks (GtkRuler *ruler) widget = GTK_WIDGET (ruler); - gc = widget->style->fg_gc[GTK_STATE_NORMAL]; - bg_gc = widget->style->bg_gc[GTK_STATE_NORMAL]; - xthickness = widget->style->xthickness; ythickness = widget->style->ythickness; @@ -181,12 +178,15 @@ gtk_vruler_draw_ticks (GtkRuler *ruler) 0, 0, widget->allocation.width, widget->allocation.height); - gdk_draw_line (ruler->backing_store, gc, - height + xthickness, - ythickness, - height + xthickness, - widget->allocation.height - ythickness); - + cr = gdk_drawable_create_cairo_context (ruler->backing_store); + gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); + + cairo_rectangle (cr, + height + xthickness, + ythickness, + 1, + widget->allocation.height - 2 * ythickness); + upper = ruler->upper / ruler->metric->pixels_per_unit; lower = ruler->lower / ruler->metric->pixels_per_unit; @@ -242,9 +242,9 @@ gtk_vruler_draw_ticks (GtkRuler *ruler) { pos = ROUND ((cur - lower) * increment); - gdk_draw_line (ruler->backing_store, gc, - height + xthickness - length, pos, - height + xthickness, pos); + cairo_rectangle (cr, + height + xthickness - length, pos, + length, 1); /* draw label */ if (i == 0) @@ -272,6 +272,9 @@ gtk_vruler_draw_ticks (GtkRuler *ruler) } } + cairo_fill (cr); + cairo_destroy (cr); + g_object_unref (layout); } @@ -279,9 +282,7 @@ gtk_vruler_draw_ticks (GtkRuler *ruler) static void gtk_vruler_draw_pos (GtkRuler *ruler) { - GtkWidget *widget; - GdkGC *gc; - int i; + GtkWidget *widget = GTK_WIDGET (ruler); gint x, y; gint width, height; gint bs_width, bs_height; @@ -291,24 +292,23 @@ gtk_vruler_draw_pos (GtkRuler *ruler) if (GTK_WIDGET_DRAWABLE (ruler)) { - widget = GTK_WIDGET (ruler); - - gc = widget->style->fg_gc[GTK_STATE_NORMAL]; xthickness = widget->style->xthickness; ythickness = widget->style->ythickness; width = widget->allocation.width - xthickness * 2; height = widget->allocation.height; - bs_height = width / 2; + bs_height = width / 2 + 2; bs_height |= 1; /* make sure it's odd */ bs_width = bs_height / 2 + 1; if ((bs_width > 0) && (bs_height > 0)) { + cairo_t *cr = gdk_drawable_create_cairo_context (widget->window); + /* If a backing store exists, restore the ruler */ - if (ruler->backing_store && ruler->non_gr_exp_gc) - gdk_draw_drawable (ruler->widget.window, - ruler->non_gr_exp_gc, + if (ruler->backing_store) + gdk_draw_drawable (widget->window, + widget->style->black_gc, ruler->backing_store, ruler->xsrc, ruler->ysrc, ruler->xsrc, ruler->ysrc, @@ -318,11 +318,15 @@ gtk_vruler_draw_pos (GtkRuler *ruler) x = (width + bs_width) / 2 + xthickness; y = ROUND ((ruler->position - ruler->lower) * increment) + (ythickness - bs_height) / 2 - 1; + + gdk_cairo_set_source_color (cr, &widget->style->fg[widget->state]); + + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + bs_width, y + bs_height / 2.); + cairo_line_to (cr, x, y + bs_height); + cairo_fill (cr); - for (i = 0; i < bs_width; i++) - gdk_draw_line (widget->window, gc, - x + i, y + i, - x + i, y + bs_height - 1 - i); + cairo_destroy (cr); ruler->xsrc = x; ruler->ysrc = y; |