summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2005-03-17 01:54:40 +0000
committerOwen Taylor <otaylor@src.gnome.org>2005-03-17 01:54:40 +0000
commit09d7eafb15099362c0ed611d775b1f2fe5f17f94 (patch)
tree288fc18e7d665e5e897409489e409c017efece2d
parenteebd4f1c4bba4d1a2b9a5e0cfd9fd34f318ee84d (diff)
downloadgtk+-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.
-rw-r--r--ChangeLog51
-rw-r--r--ChangeLog.pre-2-1051
-rw-r--r--ChangeLog.pre-2-851
-rw-r--r--gdk/gdk.symbols17
-rw-r--r--gdk/gdkcolor.c18
-rw-r--r--gdk/gdkcolor.h4
-rw-r--r--gdk/gdkdraw.c401
-rw-r--r--gdk/gdkdrawable.h14
-rw-r--r--gdk/gdkinternals.h6
-rw-r--r--gdk/gdkpango.c523
-rw-r--r--gdk/gdkpixbuf-render.c108
-rw-r--r--gdk/gdkpixbuf.h3
-rw-r--r--gdk/gdkpixmap.c13
-rw-r--r--gdk/gdkwindow.c110
-rw-r--r--gdk/x11/Makefile.am1
-rw-r--r--gdk/x11/gdkdisplay-x11.c1
-rw-r--r--gdk/x11/gdkdisplay-x11.h1
-rw-r--r--gdk/x11/gdkdrawable-x11.c450
-rw-r--r--gdk/x11/gdkdrawable-x11.h14
-rw-r--r--gdk/x11/gdkgc-x11.c371
-rw-r--r--gdk/x11/gdkpango-x11.c174
-rw-r--r--gdk/x11/gdkpixmap-x11.c10
-rw-r--r--gdk/x11/gdkprivate-x11.h9
-rw-r--r--gdk/x11/gdkwindow-x11.c18
-rw-r--r--gtk/gtkcolorsel.c191
-rw-r--r--gtk/gtkhruler.c58
-rw-r--r--gtk/gtkhsv.c341
-rw-r--r--gtk/gtkiconview.c121
-rw-r--r--gtk/gtkruler.c3
-rw-r--r--gtk/gtkruler.h2
-rw-r--r--gtk/gtksettings.c8
-rw-r--r--gtk/gtkstyle.c741
-rw-r--r--gtk/gtkvruler.c58
-rw-r--r--tests/testcairo.c3
-rw-r--r--tests/testgtkrc6
35 files changed, 1484 insertions, 2467 deletions
diff --git a/ChangeLog b/ChangeLog
index e05d594e5d..483b0c0c39 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+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.
+
2005-03-16 Matthias Clasen <mclasen@redhat.com>
* demos/gtk-demo/editable_cells.c: Also demonstrate
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index e05d594e5d..483b0c0c39 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,54 @@
+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.
+
2005-03-16 Matthias Clasen <mclasen@redhat.com>
* demos/gtk-demo/editable_cells.c: Also demonstrate
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index e05d594e5d..483b0c0c39 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,54 @@
+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.
+
2005-03-16 Matthias Clasen <mclasen@redhat.com>
* demos/gtk-demo/editable_cells.c: Also demonstrate
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index 2b7b7df049..07b1412042 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -301,6 +301,7 @@ gdk_color_equal
gdk_color_free
gdk_color_get_type G_GNUC_CONST
gdk_color_hash
+gdk_cairo_set_source_color
gdk_colormap_alloc_color
gdk_colormap_get_system
gdk_colormap_get_visual
@@ -497,7 +498,7 @@ gdk_drag_get_protocol
#if IN_HEADER(__GDK_DRAWABLE_H__)
#if IN_FILE(__GDK_DRAW_C__)
-gdk_drawable_set_cairo_target
+gdk_drawable_create_cairo_context
gdk_drawable_copy_to_image
gdk_drawable_get_clip_region
gdk_drawable_get_colormap
@@ -537,12 +538,6 @@ gdk_draw_trapezoids
#endif
#if IN_HEADER(__GDK_DRAWABLE_H__)
-#if IN_FILE(__GDK_DRAWABLE_X11_C__)
-gdk_draw_rectangle_alpha_libgtk_only
-#endif
-#endif
-
-#if IN_HEADER(__GDK_DRAWABLE_H__)
#if IN_FILE(__GDK_PANGO_C__)
gdk_draw_layout
gdk_draw_layout_line
@@ -818,6 +813,7 @@ gdk_net_wm_supports
gdk_pango_attr_embossed_new
gdk_pango_attr_stipple_new
gdk_pango_context_get
+gdk_pango_context_get_for_screen
#ifndef GDK_DISABLE_DEPRECATED
gdk_pango_context_set_colormap
#endif
@@ -833,12 +829,6 @@ gdk_pango_renderer_set_stipple
#endif
#endif
-#if IN_HEADER(__GDK_PANGO_H__)
-#if IN_FILE(__GDK_PANGO_X11_C__)
-gdk_pango_context_get_for_screen
-#endif
-#endif
-
#if IN_HEADER(__GDK_PIXBUF_H__)
#if IN_FILE(__GDK_PIXBUF_DRAWABLE_C__)
gdk_pixbuf_get_from_drawable
@@ -851,6 +841,7 @@ gdk_pixbuf_get_from_image
gdk_pixbuf_render_pixmap_and_mask
gdk_pixbuf_render_pixmap_and_mask_for_colormap
gdk_pixbuf_render_threshold_alpha
+gdk_pixbuf_set_as_cairo_source
#ifndef GDK_DISABLE_DEPRECATED
gdk_pixbuf_render_to_drawable
gdk_pixbuf_render_to_drawable_alpha
diff --git a/gdk/gdkcolor.c b/gdk/gdkcolor.c
index d2a4a55cab..f33ff790c4 100644
--- a/gdk/gdkcolor.c
+++ b/gdk/gdkcolor.c
@@ -371,5 +371,23 @@ gdk_colormap_get_system (void)
return gdk_screen_get_system_colormap (gdk_screen_get_default ());
}
+/**
+ * gdk_cairo_set_source_color:
+ * @cr: a #cairo_t
+ * @color: a #GdkColor
+ *
+ * Convenience function to set the specified GdkColor as the
+ * source color of the given Cairo context.
+ **/
+void
+gdk_cairo_set_source_color (cairo_t *cr,
+ GdkColor *color)
+{
+ cairo_set_rgb_color (cr,
+ color->red / 65535.,
+ color->green / 65535.,
+ color->blue / 65535.);
+}
+
#define __GDK_COLOR_C__
#include "gdkaliasdef.c"
diff --git a/gdk/gdkcolor.h b/gdk/gdkcolor.h
index 8754c3cd9f..df4e2ffc8c 100644
--- a/gdk/gdkcolor.h
+++ b/gdk/gdkcolor.h
@@ -1,6 +1,7 @@
#ifndef __GDK_COLOR_H__
#define __GDK_COLOR_H__
+#include <cairo.h>
#include <gdk/gdktypes.h>
#ifdef __cplusplus
@@ -111,6 +112,9 @@ gboolean gdk_color_equal (const GdkColor *colora,
GType gdk_color_get_type (void) G_GNUC_CONST;
+void gdk_cairo_set_source_color (cairo_t *cr,
+ GdkColor *color);
+
/* The following functions are deprecated */
#ifndef GDK_DISABLE_DEPRECATED
void gdk_colors_store (GdkColormap *colormap,
diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c
index b8a653d433..c5bd2d8b62 100644
--- a/gdk/gdkdraw.c
+++ b/gdk/gdkdraw.c
@@ -26,6 +26,7 @@
#include <config.h>
#include <math.h>
+#include <pango/pangocairo.h>
#include "gdkdrawable.h"
#include "gdkinternals.h"
#include "gdkwindow.h"
@@ -59,10 +60,6 @@ static void gdk_drawable_real_draw_pixbuf (GdkDrawable *draw
GdkRgbDither dither,
gint x_dither,
gint y_dither);
-static void gdk_drawable_real_draw_trapezoids (GdkDrawable *drawable,
- GdkGC *gc,
- GdkTrapezoid *trapezoids,
- gint n_trapezoids);
static void gdk_drawable_class_init (GdkDrawableClass *klass);
@@ -104,7 +101,6 @@ gdk_drawable_class_init (GdkDrawableClass *klass)
klass->get_clip_region = gdk_drawable_real_get_visible_region;
klass->get_visible_region = gdk_drawable_real_get_visible_region;
klass->draw_pixbuf = gdk_drawable_real_draw_pixbuf;
- klass->draw_trapezoids = gdk_drawable_real_draw_trapezoids;
}
/* Manipulation of drawables
@@ -872,6 +868,43 @@ gdk_draw_lines (GdkDrawable *drawable,
GDK_DRAWABLE_GET_CLASS (drawable)->draw_lines (drawable, gc, points, npoints);
}
+static void
+real_draw_glyphs (GdkDrawable *drawable,
+ GdkGC *gc,
+ PangoMatrix *matrix,
+ PangoFont *font,
+ gdouble x,
+ gdouble y,
+ PangoGlyphString *glyphs)
+{
+ GdkColor color;
+ cairo_t *cr;
+
+ cr = gdk_drawable_create_cairo_context (drawable);
+
+ _gdk_windowing_gc_get_foreground (gc, &color);
+ gdk_cairo_set_source_color (cr, &color);
+
+ if (matrix)
+ {
+ cairo_matrix_t *cairo_matrix;
+
+ cairo_matrix = cairo_matrix_create ();
+ cairo_matrix_set_affine (cairo_matrix,
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+
+ cairo_set_matrix (cr, cairo_matrix);
+ cairo_matrix_destroy (cairo_matrix);
+ }
+
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_glyph_string (cr, font, glyphs);
+
+ cairo_destroy (cr);
+}
+
/**
* gdk_draw_glyphs:
* @drawable: a #GdkDrawable
@@ -901,9 +934,9 @@ gdk_draw_glyphs (GdkDrawable *drawable,
{
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
g_return_if_fail (GDK_IS_GC (gc));
-
-
- GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs (drawable, gc, font, x, y, glyphs);
+
+ real_draw_glyphs (drawable, gc, NULL, font,
+ x, y, glyphs);
}
/**
@@ -941,9 +974,8 @@ gdk_draw_glyphs_transformed (GdkDrawable *drawable,
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
g_return_if_fail (GDK_IS_GC (gc));
- if (GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs_transformed)
- GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs_transformed (drawable, gc, matrix,
- font, x, y, glyphs);
+ real_draw_glyphs (drawable, gc, matrix, font,
+ x / PANGO_SCALE, y / PANGO_SCALE, glyphs);
}
/**
@@ -967,12 +999,31 @@ gdk_draw_trapezoids (GdkDrawable *drawable,
GdkTrapezoid *trapezoids,
gint n_trapezoids)
{
+ GdkColor color;
+ cairo_t *cr;
+ int i;
+
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
g_return_if_fail (GDK_IS_GC (gc));
g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL);
- GDK_DRAWABLE_GET_CLASS (drawable)->draw_trapezoids (drawable, gc,
- trapezoids, n_trapezoids);
+ cr = gdk_drawable_create_cairo_context (drawable);
+
+ _gdk_windowing_gc_get_foreground (gc, &color);
+ gdk_cairo_set_source_color (cr, &color);
+
+ for (i = 0; i < n_trapezoids; i++)
+ {
+ cairo_move_to (cr, trapezoids[i].x11, trapezoids[i].y1);
+ cairo_line_to (cr, trapezoids[i].x21, trapezoids[i].y1);
+ cairo_line_to (cr, trapezoids[i].x22, trapezoids[i].y2);
+ cairo_line_to (cr, trapezoids[i].x21, trapezoids[i].y2);
+ cairo_close_path (cr);
+ }
+
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
}
/**
@@ -1222,26 +1273,50 @@ gdk_drawable_real_get_visible_region (GdkDrawable *drawable)
}
/**
- * gdk_drawable_set_cairo_target:
+ * _gdk_drawable_ref_cairo_surface:
+ * @drawable: a #GdkDrawable
+ *
+ * Obtains a #cairo_surface_t for the given drawable. If a
+ * #cairo_surface_t for the drawable already exists, it will be
+ * referenced, otherwise a new surface will be created.
+ *
+ * Return value: a newly referenced #cairo_surface_t that points
+ * to @drawable. Unref with cairo_surface_destroy()
+ **/
+cairo_surface_t *
+_gdk_drawable_ref_cairo_surface (GdkDrawable *drawable)
+{
+ g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
+
+ return GDK_DRAWABLE_GET_CLASS (drawable)->ref_cairo_surface (drawable);
+}
+
+/**
+ * gdk_drawable_create_cairo_context:
* @drawable: a #GdkDrawable
- * @cr: a cairo context
*
- * Sets the given drawable as the target surface for a Cairo context.
- * Note that when @drawable is a window and gdk_window_begin_paint()
- * has been called, the target surface will be set to the temporary
- * backing pixmap, so you can only use the Cairo context until
- * the matching call to gdk_window_end_paint().
+ * Creates a Cairo context for drawing to @drawable.
*
+ * Return value: A newly created Cairo context. Free with
+ * cairo_destroy() when you are done drawing.
+ *
* Since: 2.10
**/
-void
-gdk_drawable_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr)
+cairo_t *
+gdk_drawable_create_cairo_context (GdkDrawable *drawable)
{
- g_return_if_fail (GDK_IS_DRAWABLE (drawable));
- g_return_if_fail (cr != NULL);
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
+
+ cr = cairo_create ();
- return GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_target (drawable, cr);
+ surface = _gdk_drawable_ref_cairo_surface (drawable);
+ if (surface)
+ cairo_set_target_surface (cr, surface);
+
+ return cr;
}
static void
@@ -1633,280 +1708,6 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable,
/************************************************************************/
-/* Fallback rendering code for anti-aliased trapezoids. Note that this code
- * is cut-and-pasted (with the substitution of GdkPixbuf for FT_Bitmap) between
- * here and pangoft2-render.c.
- */
-typedef struct {
- double y;
- double x1;
- double x2;
-} Position;
-
-static void
-draw_simple_trap (GdkPixbuf *pixbuf,
- int pixbuf_x,
- int pixbuf_y,
- Position *t,
- Position *b)
-{
- guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
- int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
- int pixbuf_width = gdk_pixbuf_get_width (pixbuf);
- int pixbuf_height = gdk_pixbuf_get_height (pixbuf);
- int iy = floor (t->y);
- int x1, x2, x;
- double dy = b->y - t->y;
- guchar *dest;
-
- if (iy < pixbuf_y || iy >= pixbuf_y + pixbuf_height)
- return;
-
- if (t->x1 < b->x1)
- x1 = floor (t->x1);
- else
- x1 = floor (b->x1);
-
- if (t->x2 > b->x2)
- x2 = ceil (t->x2);
- else
- x2 = ceil (b->x2);
-
- x1 = CLAMP (x1, pixbuf_x, pixbuf_x + pixbuf_width);
- x2 = CLAMP (x2, pixbuf_x, pixbuf_x + pixbuf_width);
-
- dest = pixels + (iy - pixbuf_y) * rowstride + (x1 - pixbuf_x) * 4;
-
- for (x = x1; x < x2; x++, dest += 4)
- {
- double top_left = MAX (t->x1, x);
- double top_right = MIN (t->x2, x + 1);
- double bottom_left = MAX (b->x1, x);
- double bottom_right = MIN (b->x2, x + 1);
- double c = 0.5 * dy * ((top_right - top_left) + (bottom_right - bottom_left));
-
- /* When converting to [0,255], we round up. This is intended
- * to prevent the problem of pixels that get divided into
- * multiple slices not being fully black.
- */
- int ic = c * 256;
-
- /* We already set the entire buffer to the destination color */
- dest[3] = MIN (dest[3] + ic, 255);
- }
-}
-
-static void
-interpolate_position (Position *result,
- Position *top,
- Position *bottom,
- double val,
- double val1,
- double val2)
-{
- result->y = (top->y * (val2 - val) + bottom->y * (val - val1)) / (val2 - val1);
- result->x1 = (top->x1 * (val2 - val) + bottom->x1 * (val - val1)) / (val2 - val1);
- result->x2 = (top->x2 * (val2 - val) + bottom->x2 * (val - val1)) / (val2 - val1);
-}
-
-/* This draws a trapezoid with the parallel sides aligned with
- * the X axis. We do this by subdividing the trapezoid vertically
- * into thin slices (themselves trapezoids) where two edge sides are each
- * contained within a single pixel and then rasterizing each
- * slice. There are frequently multiple slices within a single
- * line so we have to accumulate to get the final result.
- */
-static void
-draw_trapezoid (GdkPixbuf *pixbuf,
- int pixbuf_x,
- int pixbuf_y,
- GdkTrapezoid *trapezoid)
-{
- Position pos;
- Position t;
- Position b;
- gboolean done = FALSE;
-
- if (trapezoid->y1 == trapezoid->y2)
- return;
-
- pos.y = t.y = trapezoid->y1;
- pos.x1 = t.x1 = trapezoid->x11;
- pos.x2 = t.x2 = trapezoid->x21;
- b.y = trapezoid->y2;
- b.x1 = trapezoid->x12;
- b.x2 = trapezoid->x22;
-
- while (!done)
- {
- Position pos_next;
- double y_next, x1_next, x2_next;
- double ix1, ix2;
-
- /* The algorithm here is written to emphasize simplicity and
- * numerical stability as opposed to speed.
- *
- * While the end result is slicing up the polygon vertically,
- * conceptually we aren't walking in the X direction, rather we
- * are walking along the edges. When we compute crossing of
- * horizontal pixel boundaries, we use the X coordinate as the
- * interpolating variable, when we compute crossing for vertical
- * pixel boundaries, we use the Y coordinate.
- *
- * This allows us to handle almost exactly horizontal edges without
- * running into difficulties. (Almost exactly horizontal edges
- * come up frequently due to inexactness in computing, say,
- * a 90 degree rotation transformation)
- */
-
- pos_next = b;
- done = TRUE;
-
- /* Check for crossing vertical pixel boundaries */
- y_next = floor (pos.y) + 1;
- if (y_next < pos_next.y)
- {
- interpolate_position (&pos_next, &t, &b,
- y_next, t.y, b.y);
- pos_next.y = y_next;
- done = FALSE;
- }
-
- /* Check left side for crossing horizontal pixel boundaries */
- ix1 = floor (pos.x1);
-
- if (b.x1 < t.x1)
- {
- if (ix1 == pos.x1)
- x1_next = ix1 - 1;
- else
- x1_next = ix1;
-
- if (x1_next > pos_next.x1)
- {
- interpolate_position (&pos_next, &t, &b,
- x1_next, t.x1, b.x1);
- pos_next.x1 = x1_next;
- done = FALSE;
- }
- }
- else if (b.x1 > t.x1)
- {
- x1_next = ix1 + 1;
-
- if (x1_next < pos_next.x1)
- {
- interpolate_position (&pos_next, &t, &b,
- x1_next, t.x1, b.x1);
- pos_next.x1 = x1_next;
- done = FALSE;
- }
- }
-
- /* Check right side for crossing horizontal pixel boundaries */
- ix2 = floor (pos.x2);
-
- if (b.x2 < t.x2)
- {
- if (ix2 == pos.x2)
- x2_next = ix2 - 1;
- else
- x2_next = ix2;
-
- if (x2_next > pos_next.x2)
- {
- interpolate_position (&pos_next, &t, &b,
- x2_next, t.x2, b.x2);
- pos_next.x2 = x2_next;
- done = FALSE;
- }
- }
- else if (trapezoid->x22 > trapezoid->x21)
- {
- x2_next = ix2 + 1;
-
- if (x2_next < pos_next.x2)
- {
- interpolate_position (&pos_next, &t, &b,
- x2_next, t.x2, b.x2);
- pos_next.x2 = x2_next;
- done = FALSE;
- }
- }
-
- draw_simple_trap (pixbuf, pixbuf_x, pixbuf_y, &pos, &pos_next);
- pos = pos_next;
- }
-}
-
-static void
-gdk_drawable_real_draw_trapezoids (GdkDrawable *drawable,
- GdkGC *gc,
- GdkTrapezoid *trapezoids,
- gint n_trapezoids)
-{
- GdkPixbuf *pixbuf;
- double min_x, max_x, min_y, max_y;
- int x, y, width, height;
- GdkColor color;
- int i;
-
- if (n_trapezoids == 0)
- return;
-
- /* compute bounding box */
-
- min_x = max_x = trapezoids[0].x11;
- min_y = max_y = trapezoids[0].y1;
-
- for (i = 0; i < n_trapezoids; i++)
- {
- if (trapezoids[i].x11 < min_x) min_x = trapezoids[i].x11;
- if (trapezoids[i].x21 > max_x) max_x = trapezoids[i].x21;
- if (trapezoids[i].x12 < min_x) min_x = trapezoids[i].x12;
- if (trapezoids[i].x22 > max_x) max_x = trapezoids[i].x22;
- if (trapezoids[i].y1 < min_y) min_y = trapezoids[i].y1;
- if (trapezoids[i].y2 > max_y) max_y = trapezoids[i].y2;
- }
-
- /* allocate temporary pixbuf */
-
- x = floor (min_x);
- width = ceil (max_x) - x;
- y = floor (min_y);
- height = ceil (max_y) - y;
-
- if (width == 0 || height == 0)
- return;
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
- if (!pixbuf)
- return;
-
- /* Fill the pixbuf with the foreground color and alpha 0 */
-
- _gdk_windowing_gc_get_foreground (gc, &color);
- gdk_pixbuf_fill (pixbuf,
- (((color.red & 0xff00) << 16) |
- ((color.green & 0xff00) << 8) |
- ((color.blue & 0xff00))));
-
- /* draw the trapezoids into the alpha channel */
-
- for (i = 0; i < n_trapezoids; i++)
- draw_trapezoid (pixbuf, x, y, &trapezoids[i]);
-
- /* composite that onto the drawable */
-
- gdk_draw_pixbuf (drawable, gc, pixbuf,
- 0, 0, x, y, width, height,
- GDK_RGB_DITHER_NORMAL, 0, 0);
-
- g_object_unref (pixbuf);
-}
-
-/************************************************************************/
-
/**
* _gdk_drawable_get_scratch_gc:
* @drawable: A #GdkDrawable
diff --git a/gdk/gdkdrawable.h b/gdk/gdkdrawable.h
index 612ce694fd..19344954f1 100644
--- a/gdk/gdkdrawable.h
+++ b/gdk/gdkdrawable.h
@@ -170,8 +170,7 @@ struct _GdkDrawableClass
GdkTrapezoid *trapezoids,
gint n_trapezoids);
- void (*set_cairo_target) (GdkDrawable *drawable,
- cairo_t *cr);
+ cairo_surface_t *(*ref_cairo_surface) (GdkDrawable *drawable);
/* Padding for future expansion */
void (*_gdk_reserved4) (void);
@@ -392,16 +391,7 @@ GdkImage *gdk_drawable_copy_to_image (GdkDrawable *drawable,
GdkRegion *gdk_drawable_get_clip_region (GdkDrawable *drawable);
GdkRegion *gdk_drawable_get_visible_region (GdkDrawable *drawable);
-void gdk_drawable_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr);
-
-gboolean gdk_draw_rectangle_alpha_libgtk_only (GdkDrawable *drawable,
- gint x,
- gint y,
- gint width,
- gint height,
- GdkColor *color,
- guint16 alpha);
+cairo_t *gdk_drawable_create_cairo_context (GdkDrawable *drawable);
#ifdef __cplusplus
}
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 19667da3b5..8aee134d02 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -210,6 +210,8 @@ GdkImage *_gdk_drawable_copy_to_image (GdkDrawable *drawable,
gint width,
gint height);
+cairo_surface_t *_gdk_drawable_ref_cairo_surface (GdkDrawable *drawable);
+
/* GC caching */
GdkGC *_gdk_drawable_get_scratch_gc (GdkDrawable *drawable,
gboolean graphics_exposures);
@@ -260,6 +262,10 @@ void _gdk_windowing_window_clear_area_e (GdkWindow *window,
gint width,
gint height);
+void _gdk_windowing_set_surface_device_offset (cairo_surface_t *surface,
+ gint x_offset,
+ gint y_offset);
+
void _gdk_windowing_get_pointer (GdkDisplay *display,
GdkScreen **screen,
gint *x,
diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c
index d317b0faab..c94f58d724 100644
--- a/gdk/gdkpango.c
+++ b/gdk/gdkpango.c
@@ -19,8 +19,10 @@
#include <config.h>
#include <math.h>
+#include <pango/pangocairo.h>
#include "gdkcolor.h"
#include "gdkgc.h"
+#include "gdkinternals.h"
#include "gdkpango.h"
#include "gdkrgb.h"
#include "gdkprivate.h"
@@ -47,34 +49,17 @@ struct _GdkPangoRendererPrivate
gboolean override_color_set[MAX_RENDER_PART + 1];
GdkBitmap *stipple[MAX_RENDER_PART + 1];
+ cairo_surface_t *stipple_surface[MAX_RENDER_PART + 1];
gboolean embossed;
- /* When switching between the normal and shadow copies when
- * drawing shadows we can get unexpected recursion into the
- * drawing functions; the 'in_emboss' flag guards against that.
- */
- gboolean in_emboss;
-
/* Current target */
GdkDrawable *drawable;
GdkGC *base_gc;
-
- /* Cached GC, derived from base_gc */
- GdkGC *gc;
- PangoColor gc_color;
- gboolean gc_color_set;
- GdkBitmap *gc_stipple;
-
- /* we accumulate trapezoids for the same PangoRenderPart */
- GArray *trapezoids;
- PangoRenderPart trapezoid_part;
};
static PangoAttrType gdk_pango_attr_stipple_type;
static PangoAttrType gdk_pango_attr_embossed_type;
-static void flush_trapezoids (GdkPangoRenderer *gdk_renderer);
-
enum {
PROP_0,
PROP_SCREEN
@@ -89,21 +74,19 @@ gdk_pango_renderer_finalize (GObject *object)
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
int i;
- if (priv->gc)
- g_object_unref (priv->gc);
- if (priv->gc_stipple)
- g_object_unref (priv->gc_stipple);
if (priv->base_gc)
g_object_unref (priv->base_gc);
if (priv->drawable)
g_object_unref (priv->drawable);
for (i = 0; i <= MAX_RENDER_PART; i++)
+ if (priv->stipple_surface[i])
+ cairo_surface_destroy (priv->stipple_surface[i]);
+
+ for (i = 0; i <= MAX_RENDER_PART; i++)
if (priv->stipple[i])
g_object_unref (priv->stipple[i]);
- g_array_free (priv->trapezoids, TRUE);
-
G_OBJECT_CLASS (gdk_pango_renderer_parent_class)->finalize (object);
}
@@ -130,154 +113,138 @@ gdk_pango_renderer_constructor (GType type,
return object;
}
-/* Adjusts matrix and color for the renderer to draw the secondar
+/* Adjusts matrix and color for the renderer to draw the secondary
* "shadow" copy for embossed text */
static void
-emboss_renderer (PangoRenderer *renderer,
- PangoRenderPart part,
- PangoMatrix **save_matrix,
- PangoColor **save_color)
+emboss_context (cairo_t *cr)
{
- GdkPangoRendererPrivate *priv = GDK_PANGO_RENDERER(renderer)->priv;
- static const PangoColor white = { 0xffff, 0xffff, 0xffff };
- PangoMatrix tmp_matrix = PANGO_MATRIX_INIT;
+ cairo_matrix_t *tmp_matrix = cairo_matrix_create ();
+ double a, b, c, d, tx, ty;
- priv->in_emboss = TRUE;
-
- *save_color = pango_renderer_get_color (renderer, part);
- if (*save_color)
- *save_color = pango_color_copy (*save_color);
-
- *save_matrix = renderer->matrix;
- if (*save_matrix)
- {
- *save_matrix = pango_matrix_copy (*save_matrix);
- tmp_matrix = **save_matrix;
- }
-
/* The gymnastics here to adjust the matrix are because we want
* to offset by +1,+1 in device-space, not in user-space,
* so we can't just draw the layout at x + 1, y + 1
*/
- tmp_matrix.x0 += 1;
- tmp_matrix.y0 += 1;
-
- pango_renderer_set_matrix (renderer, &tmp_matrix);
- pango_renderer_set_color (renderer, part, &white);
+ cairo_get_matrix (cr, tmp_matrix);
+ cairo_matrix_get_affine (tmp_matrix, &a, &b, &c, &d, &tx, &ty);
+ cairo_matrix_set_affine (tmp_matrix, a, b, c, d, tx + 1, ty + 1);
+ cairo_set_matrix (cr, tmp_matrix);
+ cairo_matrix_destroy (tmp_matrix);
+
+ cairo_set_rgb_color (cr, 1.0, 1.0, 1.0);
}
-/* Restores from emboss_renderer() */
static void
-unemboss_renderer (PangoRenderer *renderer,
- PangoRenderPart part,
- PangoMatrix **save_matrix,
- PangoColor **save_color)
+set_part_color (GdkPangoRenderer *gdk_renderer,
+ cairo_t *cr,
+ PangoRenderPart part)
{
- GdkPangoRendererPrivate *priv = GDK_PANGO_RENDERER(renderer)->priv;
- pango_renderer_set_matrix (renderer, *save_matrix);
- pango_renderer_set_color (renderer, part, *save_color);
-
- if (*save_matrix)
- pango_matrix_free (*save_matrix);
- if (*save_color)
- pango_color_free (*save_color);
-
- priv->in_emboss = FALSE;
+ PangoColor *color = pango_renderer_get_color (PANGO_RENDERER (gdk_renderer),
+ part);
+ if (color)
+ {
+ cairo_set_rgb_color (cr,
+ color->red / 65535.,
+ color->green / 65535.,
+ color->blue / 65535.);
+ }
+ else
+ {
+ GdkColor gc_color;
+
+ _gdk_windowing_gc_get_foreground (gdk_renderer->priv->base_gc, &gc_color);
+ gdk_cairo_set_source_color (cr, &gc_color);
+ }
}
-/* Gets the GC for drawing @part. This make involve copying the base GC
- * for the renderer, in which case we keep a one-GC cache. */
-static GdkGC *
-get_gc (GdkPangoRenderer *gdk_renderer,
- PangoRenderPart part)
+static cairo_surface_t *
+get_stipple_surface (GdkPangoRenderer *gdk_renderer,
+ cairo_t *cr,
+ PangoRenderPart part)
{
- PangoRenderer *renderer = PANGO_RENDERER (gdk_renderer);
- PangoColor *color;
- GdkBitmap *stipple;
- GdkPangoRendererPrivate *priv = gdk_renderer->priv;
+ if (!gdk_renderer->priv->stipple_surface[part])
+ {
+ cairo_t *tmp_cr;
+ cairo_surface_t *surface;
+ cairo_surface_t *alpha_surface;
+ gint width, height;
- color = pango_renderer_get_color (renderer, part);
+ gdk_drawable_get_size (gdk_renderer->priv->stipple[part],
+ &width, &height);
- if (part <= MAX_RENDER_PART)
- stipple = priv->stipple[part];
- else
- stipple = NULL;
+ alpha_surface = _gdk_drawable_ref_cairo_surface (gdk_renderer->priv->stipple[part]);
- if (!color && !stipple) /* nothing override, use base_gc */
- return priv->base_gc;
- else
- {
- gboolean new_stipple = FALSE;
- gboolean new_color = FALSE;
+ surface = cairo_surface_create_similar (cairo_get_target_surface (cr),
+ CAIRO_FORMAT_ARGB32,
+ width, height);
+
+ tmp_cr = cairo_create ();
+ cairo_set_target_surface (tmp_cr, surface);
+
+ cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SRC);
+ cairo_show_surface (tmp_cr, alpha_surface, width, height);
- if (stipple != priv->gc_stipple)
- new_stipple = TRUE;
-
- if ((priv->gc_color_set && !color) ||
- (!priv->gc_color_set && color) ||
- priv->gc_color.red != color->red ||
- priv->gc_color.green != color->green ||
- priv->gc_color.blue != color->blue)
- new_color = TRUE;
+ set_part_color (gdk_renderer, tmp_cr, part);
+ cairo_set_operator (tmp_cr, CAIRO_OPERATOR_OVER);
- if (!priv->gc)
- {
- priv->gc = gdk_gc_new (priv->drawable);
- gdk_gc_copy (priv->gc, priv->base_gc);
- }
- else if (new_color && priv->gc_color_set && !color)
- {
- /* We have to recopy the original GC onto the cached GC
- * to get the default color */
- new_stipple = TRUE;
- gdk_gc_copy (priv->gc, priv->base_gc);
- }
- else if (new_stipple && priv->gc_stipple && !stipple)
- {
- /* Similarly, we need to make a new copy to restore to the
- * default stipple state (the caller may have set a stipple
- * on the GC, and even if not, gdk_gc_set_stipple (gc, NULL)
- * doesn't work currently to restore to the default X stipple) */
- new_color = TRUE;
- gdk_gc_copy (priv->gc, priv->base_gc);
- }
+ cairo_rectangle (tmp_cr, 0, 0, width, height);
+ cairo_fill (tmp_cr);
- if (new_color)
- {
- if (color)
- {
- GdkColor gdk_color;
+ cairo_destroy (tmp_cr);
+ cairo_surface_destroy (alpha_surface);
+ }
+}
- gdk_color.red = color->red;
- gdk_color.green = color->green;
- gdk_color.blue = color->blue;
-
- gdk_gc_set_rgb_fg_color (priv->gc, &gdk_color);
+static cairo_t *
+create_cairo_context (GdkPangoRenderer *gdk_renderer,
+ PangoRenderPart part)
+{
+ PangoRenderer *renderer = PANGO_RENDERER (gdk_renderer);
+ const PangoMatrix *matrix;
+ cairo_t *cr = gdk_drawable_create_cairo_context (gdk_renderer->priv->drawable);
- priv->gc_color = *color;
- priv->gc_color_set = TRUE;
- }
- else
- priv->gc_color_set = FALSE;
- }
+ if (gdk_renderer->priv->stipple[part])
+ {
+ cairo_surface_t *surface = get_stipple_surface (gdk_renderer, cr, part);
+ cairo_pattern_t *pattern;
- if (new_stipple)
- {
- if (priv->gc_stipple)
- g_object_unref (priv->gc_stipple);
+ pattern = cairo_pattern_create_for_surface (surface);
- if (stipple)
- {
- gdk_gc_set_stipple (priv->gc, stipple);
- gdk_gc_set_fill (priv->gc, GDK_STIPPLED);
- priv->gc_stipple = g_object_ref (stipple);
- }
- else
- priv->gc_stipple = NULL;
+ if (gdk_renderer->priv->base_gc->ts_x_origin != 0 ||
+ gdk_renderer->priv->base_gc->ts_y_origin != 0)
+ {
+ cairo_matrix_t *matrix = cairo_matrix_create ();
+ cairo_matrix_translate (matrix,
+ - gdk_renderer->priv->base_gc->ts_x_origin,
+ - gdk_renderer->priv->base_gc->ts_y_origin);
+ cairo_pattern_set_matrix (pattern, matrix);
+ cairo_matrix_destroy (matrix);
}
- return priv->gc;
+ cairo_set_pattern (cr, pattern);
+ cairo_pattern_destroy (pattern);
}
+ else
+ {
+ set_part_color (gdk_renderer, cr, part);
+ }
+
+ matrix = pango_renderer_get_matrix (renderer);
+ if (matrix)
+ {
+ cairo_matrix_t *cairo_matrix;
+
+ cairo_matrix = cairo_matrix_create ();
+ cairo_matrix_set_affine (cairo_matrix,
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+
+ cairo_set_matrix (cr, cairo_matrix);
+ cairo_matrix_destroy (cairo_matrix);
+ }
+
+ return cr;
}
static void
@@ -289,86 +256,104 @@ gdk_pango_renderer_draw_glyphs (PangoRenderer *renderer,
{
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
+ cairo_t *cr;
- flush_trapezoids (gdk_renderer);
+ cr = create_cairo_context (gdk_renderer,
+ PANGO_RENDER_PART_FOREGROUND);
- if (!priv->in_emboss && priv->embossed)
+ if (priv->embossed)
{
- PangoMatrix *save_matrix;
- PangoColor *save_color;
-
- emboss_renderer (renderer, PANGO_RENDER_PART_FOREGROUND, &save_matrix, &save_color);
- gdk_draw_glyphs_transformed (priv->drawable,
- get_gc (gdk_renderer, PANGO_RENDER_PART_FOREGROUND),
- renderer->matrix, font, x, y, glyphs);
- unemboss_renderer (renderer, PANGO_RENDER_PART_FOREGROUND, &save_matrix, &save_color);
+ cairo_save (cr);
+ emboss_context (cr);
+ cairo_move_to (cr, x / PANGO_SCALE, y / PANGO_SCALE);
+ pango_cairo_show_glyph_string (cr, font, glyphs);
+ cairo_restore (cr);
}
-
- gdk_draw_glyphs_transformed (priv->drawable,
- get_gc (gdk_renderer, PANGO_RENDER_PART_FOREGROUND),
- renderer->matrix, font, x, y, glyphs);
+
+ cairo_move_to (cr, x / PANGO_SCALE, y / PANGO_SCALE);
+ pango_cairo_show_glyph_string (cr, font, glyphs);
+
+ cairo_destroy (cr);
}
-/* Outputs any pending trapezoids, we do this when the part or
- * part color changes, when we are about to draw text, etc. */
-static void
-flush_trapezoids (GdkPangoRenderer *gdk_renderer)
-{
- GdkPangoRendererPrivate *priv = gdk_renderer->priv;
-
- if (!priv->trapezoids || priv->trapezoids->len == 0)
- return;
-
- gdk_draw_trapezoids (priv->drawable,
- get_gc (gdk_renderer, priv->trapezoid_part),
- (GdkTrapezoid *)priv->trapezoids->data,
- priv->trapezoids->len);
-
- g_array_set_size (priv->trapezoids, 0);
-}
+/* Draws an error underline that looks like one of:
+ * H E H
+ * /\ /\ /\ /\ /\ -
+ * A/ \ / \ / \ A/ \ / \ |
+ * \ \ / \ / /D \ \ / \ |
+ * \ \/ C \/ / \ \/ C \ | height = HEIGHT_SQUARES * square
+ * \ /\ F / \ F /\ \ |
+ * \ / \ / \ / \ \G |
+ * \ / \ / \ / \ / |
+ * \/ \/ \/ \/ -
+ * B B
+ * |----|
+ * unit_width = (HEIGHT_SQUARES - 1) * square
+ *
+ * The x, y, width, height passed in give the desired bounding box;
+ * x/width are adjusted to make the underline a integer number of units
+ * wide.
+ */
+#define HEIGHT_SQUARES 2.5
-/* Draws a single trapezoid ... we don't draw it immediately, but rather
- * cache it to join together with other trapezoids that form part of the
- * same logical shape */
static void
-gdk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
- PangoRenderPart part,
- double y1,
- double x11,
- double x21,
- double y2,
- double x12,
- double x22)
+draw_error_underline (cairo_t *cr,
+ double x,
+ double y,
+ double width,
+ double height)
{
- GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
- GdkTrapezoid trap;
+ double square = height / HEIGHT_SQUARES;
+ double unit_width = (HEIGHT_SQUARES - 1) * square;
+ int width_units = (width + unit_width / 2) / unit_width;
+ double y_top, y_bottom;
+ int i;
- if (!gdk_renderer->priv->trapezoids)
- gdk_renderer->priv->trapezoids = g_array_new (FALSE, FALSE,
- sizeof (GdkTrapezoid));
+ x += (width - width_units * unit_width);
+ width = width_units * unit_width;
+
+ y_top = y;
+ y_bottom = y + height;
- if (gdk_renderer->priv->trapezoids->len > 0 &&
- gdk_renderer->priv->trapezoid_part != part)
- flush_trapezoids (gdk_renderer);
+ /* Bottom of squiggle */
+ cairo_move_to (cr, x - square / 2, y_top + square / 2); /* A */
+ for (i = 0; i < width_units; i += 2)
+ {
+ double x_middle = x + (i + 1) * unit_width;
+ double x_right = x + (i + 2) * unit_width;
+
+ cairo_line_to (cr, x_middle, y_bottom); /* B */
+
+ if (i + 1 == width_units)
+ /* Nothing */;
+ else if (i + 2 == width_units)
+ cairo_line_to (cr, x_right + square / 2, y_top + square / 2); /* D */
+ else
+ cairo_line_to (cr, x_right, y_top + square); /* C */
+ }
- gdk_renderer->priv->trapezoid_part = part;
-
- trap.y1 = y1;
- trap.x11 = x11;
- trap.x21 = x21;
- trap.y2 = y2;
- trap.x12 = x12;
- trap.x22 = x22;
+ /* Top of squiggle */
+ for (i -= 2; i >= 0; i -= 2)
+ {
+ double x_left = x + i * unit_width;
+ double x_middle = x + (i + 1) * unit_width;
+ double x_right = x + (i + 2) * unit_width;
+
+ if (i + 1 == width_units)
+ cairo_line_to (cr, x_middle + square / 2, y_bottom - square / 2); /* G */
+ else {
+ if (i + 2 == width_units)
+ cairo_line_to (cr, x_right, y_top); /* E */
+ cairo_line_to (cr, x_middle, y_bottom - square); /* F */
+ }
+
+ cairo_line_to (cr, x_left, y_top); /* H */
+ }
- g_array_append_val (gdk_renderer->priv->trapezoids, trap);
+ cairo_close_path (cr);
+ cairo_fill (cr);
}
-/* We can't handle embossing at the level of trapezoids, because when an
- * underline is split into multiple trapezoids, the normal and shadow
- * trapezoids will be drawn mixed together. Instead, we have to emboss
- * and entire rectangle or error underline
- */
-
static void
gdk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
PangoRenderPart part,
@@ -379,20 +364,28 @@ gdk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
{
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
+ cairo_t *cr;
+
+ cr = create_cairo_context (gdk_renderer, part);
- if (!priv->in_emboss && priv->embossed && part != PANGO_RENDER_PART_BACKGROUND)
+ if (priv->embossed && part != PANGO_RENDER_PART_BACKGROUND)
{
- PangoMatrix *save_matrix;
- PangoColor *save_color;
-
- emboss_renderer (renderer, part, &save_matrix, &save_color);
- PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_rectangle (renderer, part,
- x, y, width, height);
- unemboss_renderer (renderer, part, &save_matrix, &save_color);
+ cairo_save (cr);
+ emboss_context (cr);
+ cairo_rectangle (cr,
+ (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
+ (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+
+ cairo_fill (cr);
+ cairo_restore (cr);
}
- PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_rectangle (renderer, part,
- x, y, width, height);
+ cairo_rectangle (cr,
+ (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
+ (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
}
static void
@@ -404,20 +397,25 @@ gdk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
{
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
-
- if (!priv->in_emboss && priv->embossed)
+ cairo_t *cr;
+
+ cr = create_cairo_context (gdk_renderer, PANGO_RENDER_PART_UNDERLINE);
+
+ if (priv->embossed)
{
- PangoMatrix *save_matrix;
- PangoColor *save_color;
-
- emboss_renderer (renderer, PANGO_RENDER_PART_UNDERLINE, &save_matrix, &save_color);
- PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_error_underline (renderer,
- x, y, width, height);
- unemboss_renderer (renderer, PANGO_RENDER_PART_UNDERLINE, &save_matrix, &save_color);
+ cairo_save (cr);
+ emboss_context (cr);
+ draw_error_underline (cr,
+ (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
+ (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+ cairo_restore (cr);
}
- PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_error_underline (renderer,
- x, y, width, height);
+ draw_error_underline (cr,
+ (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
+ (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+
+ cairo_destroy (cr);
}
static void
@@ -426,11 +424,14 @@ gdk_pango_renderer_part_changed (PangoRenderer *renderer,
{
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
- if (part == gdk_renderer->priv->trapezoid_part)
- flush_trapezoids (gdk_renderer);
+ if (gdk_renderer->priv->stipple_surface[part])
+ {
+ cairo_surface_destroy (gdk_renderer->priv->stipple_surface[part]);
+ gdk_renderer->priv->stipple_surface[part] = NULL;
+ }
}
-static void
+void
gdk_pango_renderer_begin (PangoRenderer *renderer)
{
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
@@ -443,14 +444,6 @@ gdk_pango_renderer_begin (PangoRenderer *renderer)
}
static void
-gdk_pango_renderer_end (PangoRenderer *renderer)
-{
- GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
-
- flush_trapezoids (gdk_renderer);
-}
-
-static void
gdk_pango_renderer_prepare_run (PangoRenderer *renderer,
PangoLayoutRun *run)
{
@@ -555,12 +548,10 @@ gdk_pango_renderer_class_init (GdkPangoRendererClass *klass)
PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
renderer_class->draw_glyphs = gdk_pango_renderer_draw_glyphs;
- renderer_class->draw_trapezoid = gdk_pango_renderer_draw_trapezoid;
renderer_class->draw_rectangle = gdk_pango_renderer_draw_rectangle;
renderer_class->draw_error_underline = gdk_pango_renderer_draw_error_underline;
renderer_class->part_changed = gdk_pango_renderer_part_changed;
renderer_class->begin = gdk_pango_renderer_begin;
- renderer_class->end = gdk_pango_renderer_end;
renderer_class->prepare_run = gdk_pango_renderer_prepare_run;
object_class->finalize = gdk_pango_renderer_finalize;
@@ -671,8 +662,6 @@ gdk_pango_renderer_set_drawable (GdkPangoRenderer *gdk_renderer,
priv = gdk_renderer->priv;
- flush_trapezoids (gdk_renderer);
-
if (priv->drawable != drawable)
{
if (priv->drawable)
@@ -707,8 +696,6 @@ gdk_pango_renderer_set_gc (GdkPangoRenderer *gdk_renderer,
priv = gdk_renderer->priv;
- flush_trapezoids (gdk_renderer);
-
if (priv->base_gc != gc)
{
if (priv->base_gc)
@@ -716,20 +703,6 @@ gdk_pango_renderer_set_gc (GdkPangoRenderer *gdk_renderer,
priv->base_gc = gc;
if (priv->base_gc)
g_object_ref (priv->base_gc);
-
- if (priv->gc)
- {
- g_object_unref (priv->gc);
- priv->gc = NULL;
- }
-
- priv->gc_color_set = FALSE;
-
- if (priv->gc_stipple)
- {
- g_object_unref (priv->gc_stipple);
- priv->gc_stipple = NULL;
- }
}
}
@@ -1419,5 +1392,33 @@ gdk_pango_context_get (void)
return gdk_pango_context_get_for_screen (gdk_screen_get_default ());
}
+/**
+ * gdk_pango_context_get_for_screen:
+ * @screen: the #GdkScreen for which the context is to be created.
+ *
+ * Creates a #PangoContext for @screen.
+ *
+ * The context must be freed when you're finished with it.
+ *
+ * When using GTK+, normally you should use gtk_widget_get_pango_context()
+ * instead of this function, to get the appropriate context for
+ * the widget you intend to render text onto.
+ *
+ * Return value: a new #PangoContext for @screen
+ *
+ * Since: 2.2
+ **/
+PangoContext *
+gdk_pango_context_get_for_screen (GdkScreen *screen)
+{
+ PangoFontMap *fontmap;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ fontmap = pango_cairo_font_map_get_default ();
+
+ return pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+}
+
#define __GDK_PANGO_C__
#include "gdkaliasdef.c"
diff --git a/gdk/gdkpixbuf-render.c b/gdk/gdkpixbuf-render.c
index e4fe24bf8a..52c54c5a02 100644
--- a/gdk/gdkpixbuf-render.c
+++ b/gdk/gdkpixbuf-render.c
@@ -329,5 +329,113 @@ gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf,
}
}
+/**
+ * gdk_pixbuf_set_as_cairo_source:
+ * @pixbuf: a #GdkPixbuf
+ * @cr: a #Cairo context
+ *
+ * Sets the given pixbuf as the source pattern for the Cairo context.
+ * The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned
+ * so that the origin of @pixbuf is at the current point.
+ **/
+void
+gdk_pixbuf_set_as_cairo_source (GdkPixbuf *pixbuf,
+ cairo_t *cr)
+{
+ gint width = gdk_pixbuf_get_width (pixbuf);
+ gint height = gdk_pixbuf_get_height (pixbuf);
+ guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
+ int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ guchar *cairo_pixels;
+ cairo_format_t format;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ static const cairo_user_data_key_t key;
+ cairo_matrix_t *matrix;
+ double x, y;
+ int j;
+
+ if (n_channels == 3)
+ format = CAIRO_FORMAT_RGB24;
+ else
+ format = CAIRO_FORMAT_ARGB32;
+
+ cairo_pixels = g_malloc (4 * width * height);
+ surface = cairo_image_surface_create_for_data ((char *)cairo_pixels, format,
+ width, height, 4 * width);
+ cairo_surface_set_user_data (surface, &key,
+ cairo_pixels, (cairo_destroy_func_t)g_free);
+
+ for (j = height; j; j--)
+ {
+ guchar *p = gdk_pixels;
+ guchar *q = cairo_pixels;
+
+ if (n_channels == 3)
+ {
+ guchar *end = p + 3 * width;
+
+ while (p < end)
+ {
+#if G_BYTE_ORDER == GDK_LSB_FIRST
+ q[0] = p[2];
+ q[1] = p[1];
+ q[2] = p[2];
+#else
+ q[0] = p[0];
+ q[1] = p[1];
+ q[2] = p[2];
+#endif
+ p += 3;
+ q += 4;
+ }
+ }
+ else
+ {
+ guchar *end = p + 4 * width;
+ guint t1,t2,t3;
+
+#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END
+
+ while (p < end)
+ {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ MULT(q[0], p[2], p[3], t1);
+ MULT(q[1], p[1], p[3], t2);
+ MULT(q[2], p[0], p[3], t3);
+ q[3] = p[3];
+#else
+ q[0] = p[3];
+ MULT(q[1], p[0], p[3], t1);
+ MULT(q[2], p[1], p[3], t2);
+ MULT(q[3], p[2], p[3], t3);
+#endif
+
+ p += 4;
+ q += 4;
+ }
+
+#undef MULT
+ }
+
+ gdk_pixels += gdk_rowstride;
+ cairo_pixels += 4 * width;
+ }
+
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (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);
+}
+
#define __GDK_PIXBUF_RENDER_C__
#include "gdkaliasdef.c"
+
diff --git a/gdk/gdkpixbuf.h b/gdk/gdkpixbuf.h
index 39c33d240d..26d72d04a8 100644
--- a/gdk/gdkpixbuf.h
+++ b/gdk/gdkpixbuf.h
@@ -81,6 +81,9 @@ GdkPixbuf *gdk_pixbuf_get_from_image (GdkPixbuf *dest,
int width,
int height);
+void gdk_pixbuf_set_as_cairo_source (GdkPixbuf *pixbuf,
+ cairo_t *cr);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c
index f4c0d05ebd..06021e60c8 100644
--- a/gdk/gdkpixmap.c
+++ b/gdk/gdkpixmap.c
@@ -144,8 +144,7 @@ static GdkImage* gdk_pixmap_copy_to_image (GdkDrawable *drawable,
gint width,
gint height);
-static void gdk_pixmap_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr);
+static cairo_surface_t *gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable);
static GdkVisual* gdk_pixmap_real_get_visual (GdkDrawable *drawable);
static gint gdk_pixmap_real_get_depth (GdkDrawable *drawable);
@@ -227,7 +226,7 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass)
drawable_class->get_colormap = gdk_pixmap_real_get_colormap;
drawable_class->get_visual = gdk_pixmap_real_get_visual;
drawable_class->_copy_to_image = gdk_pixmap_copy_to_image;
- drawable_class->set_cairo_target = gdk_pixmap_set_cairo_target;
+ drawable_class->ref_cairo_surface = gdk_pixmap_ref_cairo_surface;
}
static void
@@ -521,12 +520,10 @@ gdk_pixmap_copy_to_image (GdkDrawable *drawable,
width, height);
}
-static void
-gdk_pixmap_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr)
+static cairo_surface_t *
+gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable)
{
- gdk_drawable_set_cairo_target (((GdkPixmapObject*)drawable)->impl,
- cr);
+ return _gdk_drawable_ref_cairo_surface (((GdkPixmapObject*)drawable)->impl);
}
static GdkBitmap *
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index e509f3b376..1d36a80703 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -44,6 +44,7 @@ struct _GdkWindowPaint
GdkPixmap *pixmap;
gint x_offset;
gint y_offset;
+ cairo_surface_t *surface;
};
static GdkGC *gdk_window_create_gc (GdkDrawable *drawable,
@@ -157,8 +158,7 @@ static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
gint width,
gint height);
-static void gdk_window_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr);
+static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
static void gdk_window_real_get_size (GdkDrawable *drawable,
gint *width,
@@ -266,7 +266,7 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
drawable_class->get_colormap = gdk_window_real_get_colormap;
drawable_class->get_visual = gdk_window_real_get_visual;
drawable_class->_copy_to_image = gdk_window_copy_to_image;
- drawable_class->set_cairo_target = gdk_window_set_cairo_target;
+ drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
drawable_class->get_clip_region = gdk_window_get_clip_region;
drawable_class->get_visible_region = gdk_window_get_visible_region;
drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
@@ -973,6 +973,10 @@ gdk_window_begin_paint_region (GdkWindow *window,
gdk_pixmap_new (window,
MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1);
+ paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap);
+ _gdk_windowing_set_surface_device_offset (paint->surface,
+ - paint->x_offset, - paint->y_offset);
+
for (list = private->paint_stack; list != NULL; list = list->next)
{
GdkWindowPaint *tmp_paint = list->data;
@@ -1047,7 +1051,8 @@ gdk_window_end_paint (GdkWindow *window)
/* Reset clip region of the cached GdkGC */
gdk_gc_set_clip_region (tmp_gc, NULL);
-
+
+ cairo_surface_destroy (paint->surface);
g_object_unref (paint->pixmap);
gdk_region_destroy (paint->region);
g_free (paint);
@@ -1720,42 +1725,60 @@ gdk_window_draw_glyphs_transformed (GdkDrawable *drawable,
RESTORE_GC (gc);
}
-static GdkGC *
-gdk_window_get_bg_gc (GdkWindow *window,
- GdkWindowPaint *paint)
+static void
+gdk_window_set_bg_pattern (GdkWindow *window,
+ cairo_t *cr,
+ int x_offset,
+ int y_offset)
{
GdkWindowObject *private = (GdkWindowObject *)window;
- guint gc_mask = 0;
- GdkGCValues gc_values;
-
if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
{
- GdkWindowPaint tmp_paint = *paint;
- tmp_paint.x_offset += private->x;
- tmp_paint.y_offset += private->y;
-
- return gdk_window_get_bg_gc (GDK_WINDOW (private->parent), &tmp_paint);
+ gdk_window_set_bg_pattern (GDK_WINDOW (private->parent), cr,
+ private->x, private->y);
}
else if (private->bg_pixmap &&
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
private->bg_pixmap != GDK_NO_BG)
{
- gc_values.fill = GDK_TILED;
- gc_values.tile = private->bg_pixmap;
-
- gc_mask = GDK_GC_FILL | GDK_GC_TILE;
+ cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
+ cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
- return gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask);
+ if (x_offset != 0 || y_offset)
+ {
+ cairo_matrix_t *matrix = cairo_matrix_create ();
+ cairo_matrix_translate (matrix, x_offset, y_offset);
+ cairo_pattern_set_matrix (pattern, matrix);
+ cairo_matrix_destroy (matrix);
+ }
+
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_pattern (cr, pattern);
+ cairo_pattern_destroy (pattern);
}
else
{
- GdkGC *gc = _gdk_drawable_get_scratch_gc (paint->pixmap, FALSE);
-
- gdk_gc_set_foreground (gc, &(private->bg_color));
+ gdk_cairo_set_source_color (cr, &private->bg_color);
+ }
+}
- return g_object_ref (gc);
+static void
+region_path (cairo_t *cr,
+ GdkRegion *region)
+{
+ GdkRectangle *rectangles;
+ int n_rectangles, i;
+
+ gdk_region_get_rectangles (region, &rectangles, &n_rectangles);
+ for (i = 0; i < n_rectangles; i++)
+ {
+ cairo_rectangle (cr,
+ rectangles[i].x, rectangles[i].y,
+ rectangles[i].width, rectangles[i].height);
}
+ g_free (rectangles);
}
static void
@@ -1767,20 +1790,27 @@ gdk_window_clear_backing_rect (GdkWindow *window,
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowPaint *paint = private->paint_stack->data;
- GdkGC *tmp_gc;
+ cairo_t *cr;
if (GDK_WINDOW_DESTROYED (window))
return;
- tmp_gc = gdk_window_get_bg_gc (window, paint);
- gdk_gc_set_clip_region (tmp_gc, paint->region);
-
- gdk_draw_rectangle (window, tmp_gc, TRUE,
- x, y, width, height);
+ cr = cairo_create ();
+ cairo_set_target_surface (cr, paint->surface);
- gdk_gc_set_clip_region (tmp_gc, NULL);
-
- g_object_unref (tmp_gc);
+ gdk_window_set_bg_pattern (window, cr, 0, 0);
+
+ cairo_save (cr);
+
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_clip (cr);
+
+ region_path (cr, paint->region);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+
+ cairo_destroy (cr);
}
/**
@@ -2095,11 +2125,11 @@ gdk_window_copy_to_image (GdkDrawable *drawable,
width, height);
}
-static void
-gdk_window_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr)
+static cairo_surface_t *
+gdk_window_ref_cairo_surface (GdkDrawable *drawable)
{
GdkWindowObject *private = (GdkWindowObject*) drawable;
+ cairo_surface_t *surface;
gint x_offset, y_offset;
gdk_window_get_offsets (GDK_WINDOW (drawable), &x_offset, &y_offset);
@@ -2107,12 +2137,14 @@ gdk_window_set_cairo_target (GdkDrawable *drawable,
if (private->paint_stack)
{
GdkWindowPaint *paint = private->paint_stack->data;
- gdk_drawable_set_cairo_target (paint->pixmap, cr);
+
+ surface = paint->surface;
+ cairo_surface_reference (surface);
}
else
- gdk_drawable_set_cairo_target (private->impl, cr);
+ surface = _gdk_drawable_ref_cairo_surface (private->impl);
- cairo_translate (cr, - x_offset, - y_offset);
+ return surface;
}
/* Code for dirty-region queueing
diff --git a/gdk/x11/Makefile.am b/gdk/x11/Makefile.am
index d7c529431c..13a05aaf5a 100644
--- a/gdk/x11/Makefile.am
+++ b/gdk/x11/Makefile.am
@@ -39,7 +39,6 @@ libgdk_x11_la_SOURCES = \
gdkinput.c \
gdkkeys-x11.c \
gdkmain-x11.c \
- gdkpango-x11.c \
gdkpixmap-x11.c \
gdkpixmap-x11.h \
gdkproperty-x11.c \
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index c06603073b..b73f0ea7e1 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -208,7 +208,6 @@ gdk_display_open (const gchar *display_name)
display_x11->leader_window_title_set = FALSE;
display_x11->have_render = GDK_UNKNOWN;
- display_x11->have_render_with_trapezoids = GDK_UNKNOWN;
#ifdef HAVE_XFIXES
if (XFixesQueryExtension (display_x11->xdisplay,
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index 9392657736..198bf6a727 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -78,7 +78,6 @@ struct _GdkDisplayX11
gboolean use_xshm;
gboolean have_shm_pixmaps;
GdkTristate have_render;
- GdkTristate have_render_with_trapezoids;
gboolean have_xfixes;
gint xfixes_event_base;
diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c
index 1af5cc836d..0c49e87e43 100644
--- a/gdk/x11/gdkdrawable-x11.c
+++ b/gdk/x11/gdkdrawable-x11.c
@@ -109,20 +109,6 @@ static void gdk_x11_draw_lines (GdkDrawable *drawable,
GdkPoint *points,
gint npoints);
-static void gdk_x11_draw_glyphs (GdkDrawable *drawable,
- GdkGC *gc,
- PangoFont *font,
- gint x,
- gint y,
- PangoGlyphString *glyphs);
-static void gdk_x11_draw_glyphs_transformed (GdkDrawable *drawable,
- GdkGC *gc,
- PangoMatrix *matrix,
- PangoFont *font,
- gint x,
- gint y,
- PangoGlyphString *glyphs);
-
static void gdk_x11_draw_image (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
@@ -145,13 +131,7 @@ static void gdk_x11_draw_pixbuf (GdkDrawable *drawable,
gint x_dither,
gint y_dither);
-static void gdk_x11_draw_trapezoids (GdkDrawable *drawable,
- GdkGC *gc,
- GdkTrapezoid *trapezoids,
- gint n_trapezoids);
-
-static void gdk_x11_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr);
+static cairo_surface_t *gdk_x11_ref_cairo_surface (GdkDrawable *drawable);
static void gdk_x11_set_colormap (GdkDrawable *drawable,
GdkColormap *colormap);
@@ -166,6 +146,7 @@ static void gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass);
static void gdk_drawable_impl_x11_finalize (GObject *object);
static gpointer parent_class = NULL;
+static const cairo_user_data_key_t gdk_x11_cairo_key;
GType
_gdk_drawable_impl_x11_get_type (void)
@@ -215,13 +196,10 @@ gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
drawable_class->draw_points = gdk_x11_draw_points;
drawable_class->draw_segments = gdk_x11_draw_segments;
drawable_class->draw_lines = gdk_x11_draw_lines;
- drawable_class->draw_glyphs = gdk_x11_draw_glyphs;
- drawable_class->draw_glyphs_transformed = gdk_x11_draw_glyphs_transformed;
drawable_class->draw_image = gdk_x11_draw_image;
drawable_class->draw_pixbuf = gdk_x11_draw_pixbuf;
- drawable_class->draw_trapezoids = gdk_x11_draw_trapezoids;
- drawable_class->set_cairo_target = gdk_x11_set_cairo_target;
+ drawable_class->ref_cairo_surface = gdk_x11_ref_cairo_surface;
drawable_class->set_colormap = gdk_x11_set_colormap;
drawable_class->get_colormap = gdk_x11_get_colormap;
@@ -241,6 +219,32 @@ gdk_drawable_impl_x11_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+/**
+ * _gdk_x11_drawable_finish:
+ * @drawable: a #GdkDrawableImplX11.
+ *
+ * Performs necessary cleanup prior to freeing a pixmap or
+ * destroying a window.
+ **/
+void
+_gdk_x11_drawable_finish (GdkDrawable *drawable)
+{
+ GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
+
+ if (impl->picture)
+ {
+ XRenderFreePicture (GDK_SCREEN_XDISPLAY (impl->screen),
+ impl->picture);
+ impl->picture = None;
+ }
+
+ if (impl->cairo_surface)
+ {
+ cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
+ NULL, NULL);
+ }
+}
+
static void
try_pixmap (Display *xdisplay,
int screen,
@@ -329,94 +333,25 @@ _gdk_x11_have_render (GdkDisplay *display)
return x11display->have_render == GDK_YES;
}
-gboolean
-_gdk_x11_have_render_with_trapezoids (GdkDisplay *display)
-{
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
- GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display);
-
- if (x11display->have_render_with_trapezoids == GDK_UNKNOWN)
- {
- x11display->have_render_with_trapezoids = GDK_NO;
- if (_gdk_x11_have_render (display))
- {
- /*
- * Require protocol >= 0.4 for CompositeTrapezoids support.
- */
- int major_version, minor_version;
-
-#define XRENDER_TETRAPEZOIDS_MAJOR 0
-#define XRENDER_TETRAPEZOIDS_MINOR 4
-
- if (XRenderQueryVersion (xdisplay, &major_version,
- &minor_version))
- {
- if ((major_version == XRENDER_TETRAPEZOIDS_MAJOR) &&
- (minor_version >= XRENDER_TETRAPEZOIDS_MINOR))
- x11display->have_render_with_trapezoids = GDK_YES;
- }
- }
- }
-
- return x11display->have_render_with_trapezoids == GDK_YES;
-}
-
-static XftDraw *
-gdk_x11_drawable_get_xft_draw (GdkDrawable *drawable)
-{
- GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
-
- if (impl->xft_draw == NULL)
- {
- GdkColormap *colormap = gdk_drawable_get_colormap (drawable);
-
- if (colormap)
- {
- GdkVisual *visual;
-
- visual = gdk_colormap_get_visual (colormap);
-
- impl->xft_draw = XftDrawCreate (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
- GDK_VISUAL_XVISUAL (visual), GDK_COLORMAP_XCOLORMAP (colormap));
- }
- else if (gdk_drawable_get_depth (drawable) == 1)
- {
- impl->xft_draw = XftDrawCreateBitmap (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid);
- }
- else
- {
- g_warning ("Using Xft rendering requires the drawable argument to\n"
- "have a specified colormap. All windows have a colormap,\n"
- "however, pixmaps only have colormap by default if they\n"
- "were created with a non-NULL window argument. Otherwise\n"
- "a colormap must be set on them with gdk_drawable_set_colormap");
- return NULL;
- }
- }
-
- return impl->xft_draw;
-}
-
static Picture
gdk_x11_drawable_get_picture (GdkDrawable *drawable)
{
- XftDraw *draw = gdk_x11_drawable_get_xft_draw (drawable);
-
- return draw ? XftDrawPicture (draw) : None;
+ return None;
}
static void
-gdk_x11_drawable_update_xft_clip (GdkDrawable *drawable,
- GdkGC *gc)
+gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
+ GdkGC *gc)
{
+ GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
+ Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
GdkGCX11 *gc_private = gc ? GDK_GC_X11 (gc) : NULL;
- XftDraw *xft_draw = gdk_x11_drawable_get_xft_draw (drawable);
+ Picture picture = gdk_x11_drawable_get_picture (drawable);
if (gc && gc_private->clip_region)
{
GdkRegionBox *boxes = gc_private->clip_region->rects;
gint n_boxes = gc_private->clip_region->numRects;
-#if 0 /* Until XftDrawSetClipRectangles is there */
XRectangle *rects = g_new (XRectangle, n_boxes);
int i;
@@ -427,32 +362,18 @@ gdk_x11_drawable_update_xft_clip (GdkDrawable *drawable,
rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x;
rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y;
}
- XftDrawSetClipRectangles (xft_draw, 0, 0, rects, n_boxes);
-
- g_free (rects);
-#else
- Region xregion = XCreateRegion ();
- int i;
-
- for (i=0; i < n_boxes; i++)
- {
- XRectangle rect;
-
- rect.x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
- rect.y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
- rect.width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rect.x;
- rect.height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rect.y;
-
- XUnionRectWithRegion (&rect, xregion, xregion);
- }
- XftDrawSetClip (xft_draw, xregion);
- XDestroyRegion (xregion);
-#endif
+ XRenderSetPictureClipRectangles (xdisplay, picture,
+ 0, 0, rects, n_boxes);
+
+ g_free (rects);
}
else
{
- XftDrawSetClip (xft_draw, NULL);
+ XRenderPictureAttributes pa;
+ pa.clip_mask = None;
+ XRenderChangePicture (xdisplay, picture,
+ CPClipMask, &pa);
}
}
@@ -839,45 +760,6 @@ gdk_x11_draw_lines (GdkDrawable *drawable,
}
static void
-gdk_x11_draw_glyphs (GdkDrawable *drawable,
- GdkGC *gc,
- PangoFont *font,
- gint x,
- gint y,
- PangoGlyphString *glyphs)
-{
- gdk_x11_draw_glyphs_transformed (drawable, gc, NULL,
- font,
- x * PANGO_SCALE,
- y * PANGO_SCALE,
- glyphs);
-}
-
-static void
-gdk_x11_draw_glyphs_transformed (GdkDrawable *drawable,
- GdkGC *gc,
- PangoMatrix *matrix,
- PangoFont *font,
- gint x,
- gint y,
- PangoGlyphString *glyphs)
-{
- GdkDrawableImplX11 *impl;
- PangoRenderer *renderer;
-
- impl = GDK_DRAWABLE_IMPL_X11 (drawable);
-
- g_return_if_fail (PANGO_XFT_IS_FONT (font));
-
- renderer = _gdk_x11_renderer_get (drawable, gc);
- if (matrix)
- pango_renderer_set_matrix (renderer, matrix);
- pango_renderer_draw_glyphs (renderer, font, glyphs, x, y);
- if (matrix)
- pango_renderer_set_matrix (renderer, NULL);
-}
-
-static void
gdk_x11_draw_image (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
@@ -1501,7 +1383,7 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable,
return;
}
- gdk_x11_drawable_update_xft_clip (drawable, gc);
+ gdk_x11_drawable_update_picture_clip (drawable, gc);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
@@ -1526,239 +1408,65 @@ gdk_x11_draw_pixbuf (GdkDrawable *drawable,
}
static void
-gdk_x11_draw_trapezoids (GdkDrawable *drawable,
- GdkGC *gc,
- GdkTrapezoid *trapezoids,
- gint n_trapezoids)
+gdk_x11_cairo_surface_destroy (void *data)
{
- GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
- GdkDisplay *display = gdk_screen_get_display (screen);
- XTrapezoid *xtrapezoids;
- gint i;
+ GdkDrawableImplX11 *impl = data;
- if (!_gdk_x11_have_render_with_trapezoids (display))
- {
- GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper;
- GDK_DRAWABLE_CLASS (parent_class)->draw_trapezoids (wrapper, gc,
- trapezoids, n_trapezoids);
- return;
- }
-
- xtrapezoids = g_new (XTrapezoid, n_trapezoids);
-
- for (i = 0; i < n_trapezoids; i++)
- {
- xtrapezoids[i].top = XDoubleToFixed (trapezoids[i].y1);
- xtrapezoids[i].bottom = XDoubleToFixed (trapezoids[i].y2);
- xtrapezoids[i].left.p1.x = XDoubleToFixed (trapezoids[i].x11);
- xtrapezoids[i].left.p1.y = XDoubleToFixed (trapezoids[i].y1);
- xtrapezoids[i].left.p2.x = XDoubleToFixed (trapezoids[i].x12);
- xtrapezoids[i].left.p2.y = XDoubleToFixed (trapezoids[i].y2);
- xtrapezoids[i].right.p1.x = XDoubleToFixed (trapezoids[i].x21);
- xtrapezoids[i].right.p1.y = XDoubleToFixed (trapezoids[i].y1);
- xtrapezoids[i].right.p2.x = XDoubleToFixed (trapezoids[i].x22);
- xtrapezoids[i].right.p2.y = XDoubleToFixed (trapezoids[i].y2);
- }
-
- _gdk_x11_drawable_draw_xtrapezoids (drawable, gc,
- xtrapezoids, n_trapezoids);
-
- g_free (xtrapezoids);
+ impl->cairo_surface = NULL;
}
static cairo_surface_t *
-gdk_x11_drawable_get_cairo_surface (GdkDrawable *drawable)
+gdk_x11_ref_cairo_surface (GdkDrawable *drawable)
{
GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
- GdkColormap *colormap;
- GdkVisual *visual;
if (GDK_IS_WINDOW_IMPL_X11 (drawable) &&
GDK_WINDOW_DESTROYED (impl->wrapper))
return NULL;
- colormap = gdk_drawable_get_colormap (drawable);
- if (!colormap)
- {
- g_warning ("Using Cairo rendering requires the drawable argument to\n"
- "have a specified colormap. All windows have a colormap,\n"
- "however, pixmaps only have colormap by default if they\n"
- "were created with a non-NULL window argument. Otherwise\n"
- "a colormap must be set on them with gdk_drawable_set_colormap");
- return NULL;
- }
-
- visual = gdk_colormap_get_visual (colormap);
-
if (!impl->cairo_surface)
{
- impl->cairo_surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (impl->screen),
- impl->xid,
- GDK_VISUAL_XVISUAL (visual),
- CAIRO_FORMAT_RGB24,
- GDK_COLORMAP_XCOLORMAP (colormap));
- }
-
- return impl->cairo_surface;
-}
-
-static void
-gdk_x11_set_cairo_target (GdkDrawable *drawable,
- cairo_t *cr)
-{
- cairo_surface_t *surface = gdk_x11_drawable_get_cairo_surface (drawable);
- if (surface)
- cairo_set_target_surface (cr, surface);
-}
-
-/**
- * gdk_draw_rectangle_alpha_libgtk_only:
- * @drawable: The #GdkDrawable to draw on
- * @x: the x coordinate of the left edge of the rectangle.
- * @y: the y coordinate of the top edge of the rectangle.
- * @width: the width of the rectangle.
- * @height: the height of the rectangle.
- * @color: The color
- * @alpha: The alpha value.
- *
- * Tries to draw a filled alpha blended rectangle using the window
- * system's native routines. This is not public API and must not be
- * used by applications.
- *
- * Return value: TRUE if the rectangle could be drawn, FALSE
- * otherwise.
- **/
-gboolean
-gdk_draw_rectangle_alpha_libgtk_only (GdkDrawable *drawable,
- gint x,
- gint y,
- gint width,
- gint height,
- GdkColor *color,
- guint16 alpha)
-{
- Display *xdisplay;
- XRenderColor render_color;
- Picture pict;
- int x_offset, y_offset;
- GdkDrawable *real_drawable, *impl;
-
- g_return_val_if_fail (color != NULL, FALSE);
-
- if (!GDK_IS_WINDOW (drawable))
- return FALSE;
+ GdkVisual *visual = NULL;
- if (!_gdk_x11_have_render (gdk_drawable_get_display (drawable)))
- return FALSE;
-
- gdk_window_get_internal_paint_info (GDK_WINDOW (drawable),
- &real_drawable,
- &x_offset, &y_offset);
-
- impl = ((GdkWindowObject *)real_drawable)->impl;
-
- pict = gdk_x11_drawable_get_picture (impl);
-
- if (pict == None)
- return FALSE;
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gdk_drawable_get_display (drawable));
-
- render_color.alpha = alpha;
- render_color.red = (guint32)color->red * render_color.alpha / 0xffff;
- render_color.green = (guint32)color->green * render_color.alpha / 0xffff;
- render_color.blue = (guint32)color->blue * render_color.alpha / 0xffff;
-
- XRenderFillRectangle (xdisplay,
- PictOpOver, pict, &render_color,
- x - x_offset, y - y_offset,
- width, height);
- return TRUE;
-}
-
-void
-_gdk_x11_drawable_draw_xtrapezoids (GdkDrawable *drawable,
- GdkGC *gc,
- XTrapezoid *xtrapezoids,
- int n_trapezoids)
-{
- GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
- GdkDisplay *display = gdk_screen_get_display (screen);
- GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display);
-
- XftDraw *draw;
-
- if (!_gdk_x11_have_render_with_trapezoids (display))
- {
- /* This is the case of drawing the borders of the unknown glyph box
- * without render on the display, we need to feed it back to
- * fallback code. Not efficient, but doesn't matter.
- */
- GdkTrapezoid *trapezoids = g_new (GdkTrapezoid, n_trapezoids);
- int i;
-
- for (i = 0; i < n_trapezoids; i++)
+ visual = gdk_drawable_get_visual (drawable);
+
+ if (GDK_IS_WINDOW (drawable))
+ impl->cairo_surface = cairo_xlib_surface_create_for_window_with_visual (GDK_SCREEN_XDISPLAY (impl->screen),
+ impl->xid,
+ GDK_VISUAL_XVISUAL (visual));
+ else if (visual)
+ impl->cairo_surface = cairo_xlib_surface_create_for_pixmap_with_visual (GDK_SCREEN_XDISPLAY (impl->screen),
+ impl->xid,
+ GDK_VISUAL_XVISUAL (visual));
+ else if (gdk_drawable_get_depth (drawable) == 1)
+ impl->cairo_surface = cairo_xlib_surface_create_for_pixmap (GDK_SCREEN_XDISPLAY (impl->screen),
+ impl->xid,
+ CAIRO_FORMAT_A1);
+ else
{
- trapezoids[i].y1 = XFixedToDouble (xtrapezoids[i].top);
- trapezoids[i].y2 = XFixedToDouble (xtrapezoids[i].bottom);
- trapezoids[i].x11 = XFixedToDouble (xtrapezoids[i].left.p1.x);
- trapezoids[i].x12 = XFixedToDouble (xtrapezoids[i].left.p2.x);
- trapezoids[i].x21 = XFixedToDouble (xtrapezoids[i].right.p1.x);
- trapezoids[i].x22 = XFixedToDouble (xtrapezoids[i].right.p2.x);
+ g_warning ("Using Cairo rendering requires the drawable argument to\n"
+ "have a specified colormap. All windows have a colormap,\n"
+ "however, pixmaps only have colormap by default if they\n"
+ "were created with a non-NULL window argument. Otherwise\n"
+ "a colormap must be set on them with gdk_drawable_set_colormap");
+ return NULL;
}
- gdk_x11_draw_trapezoids (drawable, gc, trapezoids, n_trapezoids);
- g_free (trapezoids);
-
- return;
+ cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
+ drawable, gdk_x11_cairo_surface_destroy);
}
+ else
+ cairo_surface_reference (impl->cairo_surface);
- gdk_x11_drawable_update_xft_clip (drawable, gc);
- draw = gdk_x11_drawable_get_xft_draw (drawable);
-
- if (!x11display->mask_format)
- x11display->mask_format = XRenderFindStandardFormat (x11display->xdisplay,
- PictStandardA8);
-
- XRenderCompositeTrapezoids (x11display->xdisplay, PictOpOver,
- _gdk_x11_gc_get_fg_picture (gc),
- XftDrawPicture (draw),
- x11display->mask_format,
- - gc->ts_x_origin, - gc->ts_y_origin,
- xtrapezoids, n_trapezoids);
+ return impl->cairo_surface;
}
void
-_gdk_x11_drawable_draw_xft_glyphs (GdkDrawable *drawable,
- GdkGC *gc,
- XftFont *xft_font,
- XftGlyphSpec *glyphs,
- gint n_glyphs)
+_gdk_windowing_set_surface_device_offset (cairo_surface_t *surface,
+ gint x_offset,
+ gint y_offset)
{
- GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
- GdkDisplay *display = gdk_screen_get_display (screen);
- GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display);
- XftDraw *draw;
-
- gdk_x11_drawable_update_xft_clip (drawable, gc);
- draw = gdk_x11_drawable_get_xft_draw (drawable);
-
- if (_gdk_x11_have_render (display))
- {
- XftGlyphSpecRender (x11display->xdisplay, PictOpOver,
- _gdk_x11_gc_get_fg_picture (gc),
- xft_font,
- XftDrawPicture (draw),
- - gc->ts_x_origin, - gc->ts_y_origin,
- glyphs, n_glyphs);
- }
- else
- {
- XftColor color;
-
- _gdk_gc_x11_get_fg_xft_color (gc, &color);
- XftDrawGlyphSpec (draw, &color, xft_font, glyphs, n_glyphs);
- }
+ cairo_xlib_surface_set_device_offset (surface, x_offset, y_offset);
}
#define __GDK_DRAWABLE_X11_C__
diff --git a/gdk/x11/gdkdrawable-x11.h b/gdk/x11/gdkdrawable-x11.h
index 1de1e50c3e..4b3d13c69d 100644
--- a/gdk/x11/gdkdrawable-x11.h
+++ b/gdk/x11/gdkdrawable-x11.h
@@ -32,7 +32,7 @@
#include <gdk/gdkdrawable.h>
#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
+#include <X11/extensions/Xrender.h>
#ifdef __cplusplus
extern "C" {
@@ -70,7 +70,7 @@ struct _GdkDrawableImplX11
Window xid;
GdkScreen *screen;
- XftDraw *xft_draw;
+ Picture picture;
cairo_surface_t *cairo_surface;
};
@@ -92,15 +92,7 @@ void _gdk_x11_convert_to_format (guchar *src_buf,
gint height);
/* Note that the following take GdkDrawableImplX11, not the wrapper drawable */
-void _gdk_x11_drawable_draw_xtrapezoids (GdkDrawable *drawable,
- GdkGC *gc,
- XTrapezoid *xtrapezoids,
- int n_trapezoids);
-void _gdk_x11_drawable_draw_xft_glyphs (GdkDrawable *drawable,
- GdkGC *gc,
- XftFont *xft_font,
- XftGlyphSpec *glyphs,
- gint n_glyphs);
+void _gdk_x11_drawable_finish (GdkDrawable *drawable);
#ifdef __cplusplus
}
diff --git a/gdk/x11/gdkgc-x11.c b/gdk/x11/gdkgc-x11.c
index c01128de60..806e96fe76 100644
--- a/gdk/x11/gdkgc-x11.c
+++ b/gdk/x11/gdkgc-x11.c
@@ -110,9 +110,6 @@ gdk_gc_x11_finalize (GObject *object)
if (x11_gc->clip_region)
gdk_region_destroy (x11_gc->clip_region);
- if (x11_gc->fg_picture != None)
- XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture);
-
if (x11_gc->stipple)
g_object_unref (x11_gc->stipple);
if (x11_gc->tile)
@@ -396,18 +393,6 @@ gdk_x11_gc_get_values (GdkGC *gc,
}
static void
-clear_fg_picture (GdkGC *gc)
-{
- GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
-
- if (x11_gc->fg_picture != None)
- {
- XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture);
- x11_gc->fg_picture = None;
- }
-}
-
-static void
gdk_x11_gc_set_values (GdkGC *gc,
GdkGCValues *values,
GdkGCValuesMask values_mask)
@@ -447,28 +432,19 @@ gdk_x11_gc_set_values (GdkGC *gc,
if (values_mask & GDK_GC_BACKGROUND)
{
if (x11_gc->bg_pixel != values->background.pixel)
- {
- x11_gc->bg_pixel = values->background.pixel;
- if (x11_gc->fill == GDK_OPAQUE_STIPPLED)
- clear_fg_picture (gc);
- }
+ x11_gc->bg_pixel = values->background.pixel;
}
if (values_mask & GDK_GC_FILL)
{
if (x11_gc->fill != values->fill)
- {
- clear_fg_picture (gc);
- x11_gc->fill = values->fill;
- }
+ x11_gc->fill = values->fill;
}
if (values_mask & GDK_GC_STIPPLE)
{
if (x11_gc->stipple != values->stipple)
{
- if (x11_gc->fill == GDK_STIPPLED || x11_gc->fill == GDK_OPAQUE_STIPPLED)
- clear_fg_picture (gc);
if (x11_gc->stipple)
g_object_unref (x11_gc->stipple);
x11_gc->stipple = values->stipple;
@@ -481,8 +457,6 @@ gdk_x11_gc_set_values (GdkGC *gc,
{
if (x11_gc->tile != values->tile)
{
- if (x11_gc->fill == GDK_TILED)
- clear_fg_picture (gc);
if (x11_gc->tile)
g_object_unref (x11_gc->tile);
x11_gc->tile = values->tile;
@@ -882,8 +856,6 @@ gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc)
x11_dst_gc->tile = x11_src_gc->tile;
if (x11_dst_gc->tile)
g_object_ref (x11_dst_gc->tile);
-
- clear_fg_picture (dst_gc);
}
/**
@@ -943,345 +915,6 @@ gdk_x11_gc_get_xgc (GdkGC *gc)
return gc_x11->xgc;
}
-/* Various bits of the below are roughly cribbed from XFree86
- * lib/Xft/xftdraw.c, Copyright 2000, Keith Packard
- */
-
-static XRenderPictFormat *
-foreground_format (GdkGC *gc)
-{
- XRenderPictFormat pf;
-
- pf.type = PictTypeDirect;
- pf.depth = 32;
- pf.direct.redMask = 0xff;
- pf.direct.greenMask = 0xff;
- pf.direct.blueMask = 0xff;
- pf.direct.alphaMask = 0xff;
-
- return XRenderFindFormat (GDK_GC_XDISPLAY (gc),
- (PictFormatType |
- PictFormatDepth |
- PictFormatRedMask |
- PictFormatGreenMask |
- PictFormatBlueMask |
- PictFormatAlphaMask),
- &pf,
- 0);
-}
-
-static Picture
-make_fg_tile_picture (GdkGC *gc)
-{
- GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
- GdkVisual *visual = gdk_drawable_get_visual (x11_gc->tile);
- XRenderPictFormat *format = NULL;
-
- if (visual)
- {
- format = XRenderFindVisualFormat (GDK_GC_XDISPLAY (gc),
- GDK_VISUAL_XVISUAL (visual));
- }
- else if (x11_gc->depth == 1)
- {
- format = XRenderFindStandardFormat (GDK_GC_XDISPLAY (gc),
- PictStandardA1);
- }
-
- if (format)
- {
- XRenderPictureAttributes pa;
- pa.repeat = True;
-
- return XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
- GDK_PIXMAP_XID (x11_gc->tile),
- format,
- CPRepeat, &pa);
- }
-
- return None;
-}
-
-static Picture
-make_stipple_picture (GdkGC *gc)
-{
- GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
- XRenderPictFormat *format = NULL;
- XRenderPictureAttributes pa;
-
- format = XRenderFindStandardFormat (GDK_GC_XDISPLAY (gc),
- PictStandardA1);
-
- pa.repeat = True;
- return XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
- GDK_PIXMAP_XID (x11_gc->stipple),
- format,
- CPRepeat, &pa);
-}
-
-static Picture
-make_color_picture (GdkGC *gc,
- XRenderColor *color)
-{
- GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
- XRenderPictureAttributes pa;
- XRenderPictFormat *pix_format = foreground_format (gc);
- Pixmap pix;
- Picture picture;
-
- if (!pix_format)
- return None;
-
- pix = XCreatePixmap (GDK_GC_XDISPLAY (gc),
- GDK_SCREEN_XROOTWIN (x11_gc->screen),
- 1, 1, pix_format->depth);
- pa.repeat = True;
- picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
- pix,
- pix_format,
- CPRepeat, &pa);
- XFreePixmap (GDK_GC_XDISPLAY (gc), pix);
-
- XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
- picture, color,
- 0, 0, 1, 1);
-
- return picture;
-}
-
-static void
-get_bg_color (GdkGC *gc,
- XRenderColor *render_color)
-{
- GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
- GdkColormap *cmap;
-
- cmap = gdk_gc_get_colormap (gc);
-
- if (cmap)
- {
- GdkColor color;
-
- gdk_colormap_query_color (cmap, x11_gc->bg_pixel, &color);
-
- render_color->alpha = 0xffff;
- render_color->red = color.red;
- render_color->green = color.green;
- render_color->blue = color.blue;
- }
- else /* Not worth warning, just use black */
- {
- render_color->alpha = 0xffff;
- render_color->red = 0;
- render_color->green = 0;
- render_color->blue = 0;
- }
-}
-
-/**
- * _gdk_x11_gc_get_fg_picture:
- * @gc: a #GdkGC
- *
- * Gets a Xrender Picture object suitable for being the source
- * drawable for drawing with the foreground the graphics context.
- *
- * Return value: a Picture, owned by the GC; this cannot be
- * used over subsequent modification of the GC.
- **/
-Picture
-_gdk_x11_gc_get_fg_picture (GdkGC *gc)
-{
- GdkGCX11 *x11_gc;
- gboolean new = FALSE;
- XftColor xftcolor;
- GdkFill fill;
- int width, height;
-
- g_return_val_if_fail (GDK_IS_GC_X11 (gc), None);
-
- if (!_gdk_x11_have_render (GDK_GC_DISPLAY (gc)))
- return None;
-
- x11_gc = GDK_GC_X11 (gc);
-
- fill = GDK_SOLID;
- width = 1;
- height = 1;
-
- switch (x11_gc->fill)
- {
- case GDK_SOLID:
- break;
- case GDK_TILED:
- if (x11_gc->tile)
- {
- if (!x11_gc->fg_picture)
- x11_gc->fg_picture = make_fg_tile_picture (gc);
-
- if (x11_gc->fg_picture != None)
- return x11_gc->fg_picture;
- }
- break;
- case GDK_STIPPLED:
- case GDK_OPAQUE_STIPPLED:
- if (x11_gc->stipple)
- {
- gdk_drawable_get_size (x11_gc->stipple, &width, &height);
- fill = x11_gc->fill;
- }
- break;
- }
-
- if (x11_gc->fg_picture == None)
- {
- XRenderPictureAttributes pa;
- XRenderPictFormat *pix_format = foreground_format (gc);
- Pixmap pix;
-
- if (!pix_format)
- return None;
-
- pix = XCreatePixmap (GDK_GC_XDISPLAY (gc),
- GDK_SCREEN_XROOTWIN (x11_gc->screen),
- width, height, pix_format->depth);
- pa.repeat = True;
- x11_gc->fg_picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
- pix,
- pix_format,
- CPRepeat, &pa);
- XFreePixmap (GDK_GC_XDISPLAY (gc), pix);
-
- new = TRUE;
- }
-
- _gdk_gc_x11_get_fg_xft_color (gc, &xftcolor);
-
- if (x11_gc->fg_picture_color.alpha != 0xffff ||
- x11_gc->fg_picture_color.red != xftcolor.color.red ||
- x11_gc->fg_picture_color.green != xftcolor.color.green ||
- x11_gc->fg_picture_color.blue != xftcolor.color.blue)
- {
- x11_gc->fg_picture_color.alpha = 0xffff;
- x11_gc->fg_picture_color.red = xftcolor.color.red;
- x11_gc->fg_picture_color.green = xftcolor.color.green;
- x11_gc->fg_picture_color.blue = xftcolor.color.blue;
-
- new = TRUE;
- }
-
- switch (fill)
- {
- case GDK_SOLID:
- XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
- x11_gc->fg_picture, &x11_gc->fg_picture_color,
- 0, 0, width, height);
- break;
- case GDK_STIPPLED:
- {
- Picture stipple_picture = make_stipple_picture (gc);
-
- XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
- x11_gc->fg_picture, &x11_gc->fg_picture_color,
- 0, 0, width, height);
- XRenderComposite (GDK_GC_XDISPLAY (gc),
- PictOpInReverse,
- stipple_picture, None, x11_gc->fg_picture,
- 0, 0, 0, 0, 0, 0, width, height);
-
- XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), stipple_picture);
- }
- break;
- case GDK_OPAQUE_STIPPLED:
- {
- XRenderColor bg_color;
-
- Picture stipple_picture = make_stipple_picture (gc);
- Picture fg_picture = make_color_picture (gc, &x11_gc->fg_picture_color);
-
- get_bg_color (gc, &bg_color);
-
- XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
- x11_gc->fg_picture, &bg_color,
- 0, 0, width, height);
- XRenderComposite (GDK_GC_XDISPLAY (gc),
- PictOpOver,
- fg_picture, stipple_picture, x11_gc->fg_picture,
- 0, 0, 0, 0, 0, 0, width, height);
-
- XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), stipple_picture);
- XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), fg_picture);
- }
- break;
- case GDK_TILED:
- g_assert_not_reached (); /* handled above */
- break;
- }
-
- return x11_gc->fg_picture;
-}
-
-/**
- * _gdk_gc_x11_get_fg_xft_color:
- * @gc: a #GdkGC
- * @xftcolor: location to store the color
- *
- * Gets the foreground color of the GC as a XftColor.
- **/
-void
-_gdk_gc_x11_get_fg_xft_color (GdkGC *gc,
- XftColor *xftcolor)
-{
- GdkGCX11 *x11_gc;
- GdkColormap *cmap;
- GdkColor color;
-
- g_return_if_fail (GDK_IS_GC_X11 (gc));
-
- x11_gc = GDK_GC_X11 (gc);
-
- cmap = gdk_gc_get_colormap (gc);
-
- xftcolor->pixel = x11_gc->fg_pixel;
-
- if (cmap)
- {
- gdk_colormap_query_color (cmap, xftcolor->pixel, &color);
- xftcolor->color.alpha = 0xffff;
- xftcolor->color.red = color.red;
- xftcolor->color.green = color.green;
- xftcolor->color.blue = color.blue;
- }
- else if (x11_gc->depth == 1)
- {
- /* Drawing with Xft on a bitmap is a bit bizzare; it
- * takes alpha >= 0x8000 to mean 'set to 1' and
- * alpha < 0x8000 to mean 'set to 0'.
- */
- if (xftcolor->pixel)
- {
- xftcolor->color.red = 0xffff;
- xftcolor->color.green = 0xffff;
- xftcolor->color.blue = 0xffff;
- xftcolor->color.alpha = 0xffff;
- }
- else
- {
- xftcolor->color.red = 0;
- xftcolor->color.green = 0;
- xftcolor->color.blue = 0;
- xftcolor->color.alpha = 0;
- }
- }
- else
- {
- g_warning ("Using Xft rendering requires the GC argument to have a\n"
- "specified colormap. If the GC was created for a drawable\n"
- "with a colormap, the colormap will be set on the GC\n"
- "automatically. Otherwise, a colormap must be set on it with"
- "gdk_gc_set_colormap");
- }
-}
-
void
_gdk_windowing_gc_get_foreground (GdkGC *gc,
GdkColor *color)
diff --git a/gdk/x11/gdkpango-x11.c b/gdk/x11/gdkpango-x11.c
deleted file mode 100644
index 9db3f3567a..0000000000
--- a/gdk/x11/gdkpango-x11.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2000 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <stdlib.h>
-
-#include "gdkx.h"
-#include "gdkdisplay-x11.h"
-#include "gdkpango.h"
-#include <pango/pangoxft.h>
-#include <pango/pangoxft-render.h>
-#include "gdkalias.h"
-
-#include <math.h>
-
-typedef struct _GdkX11Renderer GdkX11Renderer;
-typedef struct _GdkX11RendererClass GdkX11RendererClass;
-
-#define GDK_TYPE_X11_RENDERER (_gdk_x11_renderer_get_type())
-#define GDK_X11_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_X11_RENDERER, GdkX11Renderer))
-#define GDK_IS_X11_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_X11_RENDERER))
-#define GDK_X11_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_X11_RENDERER, GdkX11RendererClass))
-#define GDK_IS_X11_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_X11_RENDERER))
-#define GDK_X11_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_X11_RENDERER, GdkX11RendererClass))
-
-#define MAX_RENDER_PART PANGO_RENDER_PART_STRIKETHROUGH
-
-struct _GdkX11Renderer
-{
- PangoXftRenderer parent_instance;
-
- XRenderPictFormat *mask_format;
-
- GdkDrawable *drawable;
- GdkGC *gc;
-};
-
-struct _GdkX11RendererClass
-{
- PangoXftRendererClass parent_class;
-};
-
-G_DEFINE_TYPE (GdkX11Renderer, _gdk_x11_renderer, PANGO_TYPE_XFT_RENDERER)
-
-static void
-gdk_x11_renderer_finalize (GObject *object)
-{
- G_OBJECT_CLASS (_gdk_x11_renderer_parent_class)->finalize (object);
-}
-
-static void
-gdk_x11_renderer_composite_trapezoids (PangoXftRenderer *xftrenderer,
- PangoRenderPart part,
- XTrapezoid *trapezoids,
- int n_trapezoids)
-{
- /* Because we only use this renderer for "draw_glyphs()" calls, we
- * won't hit this code path much. However, it is hit for drawing
- * the "unknown glyph" hex squares. We can safely ignore the part,
- */
- GdkX11Renderer *x11_renderer = GDK_X11_RENDERER (xftrenderer);
-
- _gdk_x11_drawable_draw_xtrapezoids (x11_renderer->drawable,
- x11_renderer->gc,
- trapezoids, n_trapezoids);
-
-}
-
-static void
-gdk_x11_renderer_composite_glyphs (PangoXftRenderer *xftrenderer,
- XftFont *xft_font,
- XftGlyphSpec *glyphs,
- gint n_glyphs)
-{
- GdkX11Renderer *x11_renderer = GDK_X11_RENDERER (xftrenderer);
-
- _gdk_x11_drawable_draw_xft_glyphs (x11_renderer->drawable,
- x11_renderer->gc,
- xft_font, glyphs, n_glyphs);
-}
-
-static void
-_gdk_x11_renderer_init (GdkX11Renderer *renderer)
-{
-}
-
-static void
-_gdk_x11_renderer_class_init (GdkX11RendererClass *klass)
-{
- PangoXftRendererClass *xftrenderer_class = PANGO_XFT_RENDERER_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- xftrenderer_class->composite_glyphs = gdk_x11_renderer_composite_glyphs;
- xftrenderer_class->composite_trapezoids = gdk_x11_renderer_composite_trapezoids;
-
- object_class->finalize = gdk_x11_renderer_finalize;
-}
-
-PangoRenderer *
-_gdk_x11_renderer_get (GdkDrawable *drawable,
- GdkGC *gc)
-{
- GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
- GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
- GdkX11Renderer *x11_renderer;
-
- if (!screen_x11->renderer)
- {
- screen_x11->renderer = g_object_new (GDK_TYPE_X11_RENDERER,
- "display", GDK_SCREEN_XDISPLAY (screen),
- "screen", GDK_SCREEN_XNUMBER (screen),
- NULL);
- }
-
- x11_renderer = GDK_X11_RENDERER (screen_x11->renderer);
-
- x11_renderer->drawable = drawable;
- x11_renderer->gc = gc;
-
- return screen_x11->renderer;
-}
-
-/**
- * gdk_pango_context_get_for_screen:
- * @screen: the #GdkScreen for which the context is to be created.
- *
- * Creates a #PangoContext for @screen.
- *
- * The context must be freed when you're finished with it.
- *
- * When using GTK+, normally you should use gtk_widget_get_pango_context()
- * instead of this function, to get the appropriate context for
- * the widget you intend to render text onto.
- *
- * Return value: a new #PangoContext for @screen
- *
- * Since: 2.2
- **/
-PangoContext *
-gdk_pango_context_get_for_screen (GdkScreen *screen)
-{
- PangoContext *context;
-
- g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
- if (screen->closed)
- return NULL;
-
- context = pango_xft_get_context (GDK_SCREEN_XDISPLAY (screen),
- GDK_SCREEN_X11 (screen)->screen_num);
-
- g_object_set_data (G_OBJECT (context), "gdk-pango-screen", screen);
-
- return context;
-}
-
-#define __GDK_PANGO_X11_C__
-#include "gdkaliasdef.c"
diff --git a/gdk/x11/gdkpixmap-x11.c b/gdk/x11/gdkpixmap-x11.c
index 6181bccb5d..501c4c3edd 100644
--- a/gdk/x11/gdkpixmap-x11.c
+++ b/gdk/x11/gdkpixmap-x11.c
@@ -132,14 +132,8 @@ gdk_pixmap_impl_x11_finalize (GObject *object)
{
GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (impl);
- if (draw_impl->xft_draw)
- XftDrawDestroy (draw_impl->xft_draw);
-
- if (draw_impl->cairo_surface)
- {
- cairo_surface_destroy (draw_impl->cairo_surface);
- draw_impl->cairo_surface = NULL;
- }
+
+ _gdk_x11_drawable_finish (GDK_DRAWABLE (draw_impl));
if (!impl->is_foreign)
XFreePixmap (GDK_DISPLAY_XDISPLAY (display), GDK_PIXMAP_XID (wrapper));
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 3152375d96..8554beb762 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -41,8 +41,6 @@
#include <config.h>
-#include <X11/extensions/Xrender.h>
-
#define GDK_TYPE_GC_X11 (_gdk_gc_x11_get_type ())
#define GDK_GC_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_GC_X11, GdkGCX11))
#define GDK_GC_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GC_X11, GdkGCX11Class))
@@ -70,8 +68,6 @@ struct _GdkGCX11
GdkBitmap *stipple;
GdkPixmap *tile;
- Picture fg_picture;
- XRenderColor fg_picture_color;
gulong fg_pixel;
gulong bg_pixel;
};
@@ -109,11 +105,6 @@ gint _gdk_send_xevent (GdkDisplay *display,
GType _gdk_gc_x11_get_type (void);
gboolean _gdk_x11_have_render (GdkDisplay *display);
-gboolean _gdk_x11_have_render_with_trapezoids (GdkDisplay *display);
-
-Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc);
-void _gdk_gc_x11_get_fg_xft_color (GdkGC *gc,
- XftColor *xftcolor);
GdkGC *_gdk_x11_gc_new (GdkDrawable *drawable,
GdkGCValues *values,
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index ac0883b658..bd86efdb83 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -842,6 +842,7 @@ gdk_window_new (GdkWindow *parent,
}
private->bg_color.pixel = BlackPixel (xdisplay, screen_x11->screen_num);
+ private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
xattributes.background_pixel = private->bg_color.pixel;
private->bg_pixmap = NULL;
@@ -1128,7 +1129,6 @@ _gdk_windowing_window_destroy (GdkWindow *window,
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkToplevelX11 *toplevel;
- GdkDrawableImplX11 *draw_impl;
g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1141,19 +1141,7 @@ _gdk_windowing_window_destroy (GdkWindow *window,
if (toplevel)
gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
- draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
-
- if (draw_impl->xft_draw)
- {
- XftDrawDestroy (draw_impl->xft_draw);
- draw_impl->xft_draw = NULL;
- }
-
- if (draw_impl->cairo_surface)
- {
- cairo_surface_destroy (draw_impl->cairo_surface);
- draw_impl->cairo_surface = NULL;
- }
+ _gdk_x11_drawable_finish (private->impl);
if (!recursing && !foreign_destroy)
{
@@ -2773,6 +2761,7 @@ gdk_window_set_background (GdkWindow *window,
const GdkColor *color)
{
GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkColormap *colormap = gdk_drawable_get_colormap (window);
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
@@ -2782,6 +2771,7 @@ gdk_window_set_background (GdkWindow *window,
GDK_WINDOW_XID (window), color->pixel);
private->bg_color = *color;
+ gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
if (private->bg_pixmap &&
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
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, &GTK_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 (&GTK_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;
diff --git a/tests/testcairo.c b/tests/testcairo.c
index 9759adf0d3..2e6eb7264e 100644
--- a/tests/testcairo.c
+++ b/tests/testcairo.c
@@ -205,8 +205,7 @@ on_expose_event (GtkWidget *widget,
{
cairo_t *cr;
- cr = cairo_create ();
- gdk_drawable_set_cairo_target (GDK_DRAWABLE (widget->window), cr);
+ cr = gdk_drawable_create_cairo_context (widget->window);
draw (cr, widget->allocation.width, widget->allocation.height);
diff --git a/tests/testgtkrc b/tests/testgtkrc
index f15d2531e0..dbe3acfa74 100644
--- a/tests/testgtkrc
+++ b/tests/testgtkrc
@@ -122,6 +122,12 @@ style 'button_list' = 'button'
}
widget "main window.*GtkScrolledWindow.*GtkButton*" style "button_list"
+style "checkbutton" {
+# GtkCheckButton::indicator-size = 27
+}
+
+class "GtkCheckButton" style "checkbutton"
+
class "GtkScrollbar" style "red-bar"