2457 lines
73 KiB
Diff
2457 lines
73 KiB
Diff
http://mail.gnome.org/archives/performance-list/2006-October/msg00063.html
|
||
|
||
From: Xan Lópe
|
||
To: ext Matt Hoosier
|
||
Cc: performance-list gnome org
|
||
Subject: Re: [patch] Remove pangocairo from Gtk+ 2.8.20
|
||
Date: Mon, 30 Oct 2006 14:31:56 +0200
|
||
Hi,
|
||
|
||
I've upgraded your patch against GTK+ 2.10.6, and we are getting great
|
||
performance figures compared to GTK+ 2.10.6 with pangocairo too
|
||
(basically at the level of GTK+ 2.6.10 again). Right now I'm working on
|
||
a python/cairo script to get some nice graphics from a torture test
|
||
session with several GTK+s, hope to get it ready soon.
|
||
|
||
Index: gtk+-2.10.6/configure.in
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/configure.in 2006-10-30 12:59:28.000000000 +0000
|
||
+++ gtk+-2.10.6/configure.in 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -1435,7 +1435,7 @@
|
||
if test "x$gdktarget" = "xwin32"; then
|
||
PANGO_PACKAGES="pangowin32 pangocairo"
|
||
else
|
||
- PANGO_PACKAGES="pango pangocairo"
|
||
+ PANGO_PACKAGES="pango pangocairo pangoxft"
|
||
fi
|
||
|
||
AC_MSG_CHECKING(Pango flags)
|
||
Index: gtk+-2.10.6/gdk/gdkaliasdef.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/gdkaliasdef.c 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/gdkaliasdef.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -1799,9 +1799,6 @@
|
||
#undef gdk_pango_context_get
|
||
extern __typeof (gdk_pango_context_get) gdk_pango_context_get __attribute((alias("IA__gdk_pango_context_get"), visibility("default")));
|
||
|
||
-#undef gdk_pango_context_get_for_screen
|
||
-extern __typeof (gdk_pango_context_get_for_screen) gdk_pango_context_get_for_screen __attribute((alias("IA__gdk_pango_context_get_for_screen"), visibility("default")));
|
||
-
|
||
#ifndef GDK_DISABLE_DEPRECATED
|
||
#undef gdk_pango_context_set_colormap
|
||
extern __typeof (gdk_pango_context_set_colormap) gdk_pango_context_set_colormap __attribute((alias("IA__gdk_pango_context_set_colormap"), visibility("default")));
|
||
@@ -1836,6 +1833,13 @@
|
||
|
||
#endif
|
||
#endif
|
||
+#if IN_HEADER(__GDK_PANGO_H__)
|
||
+#if IN_FILE(__GDK_PANGO_X11_C__)
|
||
+#undef gdk_pango_context_get_for_screen
|
||
+extern __typeof (gdk_pango_context_get_for_screen) gdk_pango_context_get_for_screen __attribute((alias("IA__gdk_pango_context_get_for_screen"), visibility("default")));
|
||
+
|
||
+#endif
|
||
+#endif
|
||
#if IN_HEADER(__GDK_PIXBUF_H__)
|
||
#if IN_FILE(__GDK_PIXBUF_DRAWABLE_C__)
|
||
#undef gdk_pixbuf_get_from_drawable
|
||
Index: gtk+-2.10.6/gdk/gdkalias.h
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/gdkalias.h 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/gdkalias.h 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -1796,9 +1796,6 @@
|
||
extern __typeof (gdk_pango_context_get) IA__gdk_pango_context_get __attribute((visibility("hidden")));
|
||
#define gdk_pango_context_get IA__gdk_pango_context_get
|
||
|
||
-extern __typeof (gdk_pango_context_get_for_screen) IA__gdk_pango_context_get_for_screen __attribute((visibility("hidden")));
|
||
-#define gdk_pango_context_get_for_screen IA__gdk_pango_context_get_for_screen
|
||
-
|
||
#ifndef GDK_DISABLE_DEPRECATED
|
||
extern __typeof (gdk_pango_context_set_colormap) IA__gdk_pango_context_set_colormap __attribute((visibility("hidden")));
|
||
#define gdk_pango_context_set_colormap IA__gdk_pango_context_set_colormap
|
||
@@ -1833,6 +1830,13 @@
|
||
|
||
#endif
|
||
#endif
|
||
+#if IN_HEADER(__GDK_PANGO_H__)
|
||
+#if IN_FILE(__GDK_PANGO_X11_C__)
|
||
+extern __typeof (gdk_pango_context_get_for_screen) IA__gdk_pango_context_get_for_screen __attribute((visibility("hidden")));
|
||
+#define gdk_pango_context_get_for_screen IA__gdk_pango_context_get_for_screen
|
||
+
|
||
+#endif
|
||
+#endif
|
||
#if IN_HEADER(__GDK_PIXBUF_H__)
|
||
#if IN_FILE(__GDK_PIXBUF_DRAWABLE_C__)
|
||
extern __typeof (gdk_pixbuf_get_from_drawable) IA__gdk_pixbuf_get_from_drawable __attribute((visibility("hidden")));
|
||
Index: gtk+-2.10.6/gdk/gdkdraw.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/gdkdraw.c 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/gdkdraw.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -909,9 +909,9 @@
|
||
{
|
||
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
|
||
g_return_if_fail (GDK_IS_GC (gc));
|
||
-
|
||
- real_draw_glyphs (drawable, gc, NULL, font,
|
||
- x, y, glyphs);
|
||
+
|
||
+
|
||
+ GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs (drawable, gc, font, x, y, glyphs);
|
||
}
|
||
|
||
/**
|
||
@@ -949,8 +949,9 @@
|
||
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
|
||
g_return_if_fail (GDK_IS_GC (gc));
|
||
|
||
- real_draw_glyphs (drawable, gc, matrix, font,
|
||
- x / PANGO_SCALE, y / PANGO_SCALE, glyphs);
|
||
+ if (GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs_transformed)
|
||
+ GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs_transformed (drawable, gc, matrix,
|
||
+ font, x, y, glyphs);
|
||
}
|
||
|
||
/**
|
||
@@ -974,28 +975,12 @@
|
||
GdkTrapezoid *trapezoids,
|
||
gint n_trapezoids)
|
||
{
|
||
- 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);
|
||
|
||
- cr = gdk_cairo_create (drawable);
|
||
- _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE);
|
||
-
|
||
- 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);
|
||
+ GDK_DRAWABLE_GET_CLASS (drawable)->draw_trapezoids (drawable, gc,
|
||
+ trapezoids, n_trapezoids);
|
||
}
|
||
|
||
/**
|
||
Index: gtk+-2.10.6/gdk/gdkpango.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/gdkpango.c 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/gdkpango.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -50,19 +50,34 @@
|
||
GdkBitmap *stipple[MAX_RENDER_PART + 1];
|
||
gboolean embossed;
|
||
|
||
- cairo_t *cr;
|
||
- PangoRenderPart last_part;
|
||
+ /* 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;
|
||
|
||
gboolean gc_changed;
|
||
+
|
||
+ /* 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
|
||
@@ -77,6 +92,10 @@
|
||
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)
|
||
@@ -86,6 +105,8 @@
|
||
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);
|
||
}
|
||
|
||
@@ -112,25 +133,6 @@
|
||
return object;
|
||
}
|
||
|
||
-/* Adjusts matrix and color for the renderer to draw the secondary
|
||
- * "shadow" copy for embossed text */
|
||
-static void
|
||
-emboss_context (cairo_t *cr)
|
||
-{
|
||
- cairo_matrix_t tmp_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
|
||
- */
|
||
- cairo_get_matrix (cr, &tmp_matrix);
|
||
- tmp_matrix.x0 += 1.0;
|
||
- tmp_matrix.y0 += 1.0;
|
||
- cairo_set_matrix (cr, &tmp_matrix);
|
||
-
|
||
- cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||
-}
|
||
-
|
||
static inline gboolean
|
||
color_equal (PangoColor *c1, PangoColor *c2)
|
||
{
|
||
@@ -146,74 +148,154 @@
|
||
return FALSE;
|
||
}
|
||
|
||
-static cairo_t *
|
||
-get_cairo_context (GdkPangoRenderer *gdk_renderer,
|
||
- PangoRenderPart part)
|
||
+/* Adjusts matrix and color for the renderer to draw the secondar
|
||
+ * "shadow" copy for embossed text */
|
||
+static void
|
||
+emboss_renderer (PangoRenderer *renderer,
|
||
+ PangoRenderPart part,
|
||
+ PangoMatrix **save_matrix,
|
||
+ PangoColor **save_color)
|
||
+{
|
||
+ GdkPangoRendererPrivate *priv = GDK_PANGO_RENDERER(renderer)->priv;
|
||
+ static const PangoColor white = { 0xffff, 0xffff, 0xffff };
|
||
+ PangoMatrix tmp_matrix = PANGO_MATRIX_INIT;
|
||
+
|
||
+ 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);
|
||
+}
|
||
+
|
||
+/* Restores from emboss_renderer() */
|
||
+static void
|
||
+unemboss_renderer (PangoRenderer *renderer,
|
||
+ PangoRenderPart part,
|
||
+ PangoMatrix **save_matrix,
|
||
+ PangoColor **save_color)
|
||
+{
|
||
+ 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;
|
||
+}
|
||
+
|
||
+/* 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)
|
||
{
|
||
PangoRenderer *renderer = PANGO_RENDERER (gdk_renderer);
|
||
+ PangoColor *color;
|
||
+ GdkBitmap *stipple;
|
||
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
|
||
|
||
- if (!priv->cr)
|
||
+ color = pango_renderer_get_color (renderer, part);
|
||
+
|
||
+ if (part <= MAX_RENDER_PART)
|
||
+ stipple = priv->stipple[part];
|
||
+ else
|
||
+ stipple = NULL;
|
||
+
|
||
+ if (!color && !stipple) /* nothing override, use base_gc */
|
||
+ return priv->base_gc;
|
||
+ else
|
||
{
|
||
- const PangoMatrix *matrix;
|
||
+ gboolean new_stipple = FALSE;
|
||
+ gboolean new_color = FALSE;
|
||
|
||
- priv->cr = gdk_cairo_create (priv->drawable);
|
||
+ if (stipple != priv->gc_stipple)
|
||
+ new_stipple = TRUE;
|
||
|
||
- matrix = pango_renderer_get_matrix (renderer);
|
||
- if (matrix)
|
||
+ 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;
|
||
+
|
||
+ if (!priv->gc)
|
||
{
|
||
- cairo_matrix_t cairo_matrix;
|
||
-
|
||
- cairo_matrix_init (&cairo_matrix,
|
||
- matrix->xx, matrix->yx,
|
||
- matrix->xy, matrix->yy,
|
||
- matrix->x0, matrix->y0);
|
||
- cairo_set_matrix (priv->cr, &cairo_matrix);
|
||
+ 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);
|
||
}
|
||
- }
|
||
-
|
||
- if (part != priv->last_part)
|
||
- {
|
||
- PangoColor *pango_color;
|
||
- GdkColor *color;
|
||
- GdkColor tmp_color;
|
||
- gboolean changed;
|
||
|
||
- pango_color = pango_renderer_get_color (renderer, part);
|
||
-
|
||
- if (priv->last_part != -1)
|
||
- changed = priv->gc_changed ||
|
||
- priv->stipple[priv->last_part] != priv->stipple[part] ||
|
||
- !color_equal (pango_color,
|
||
- pango_renderer_get_color (renderer, priv->last_part));
|
||
- else
|
||
- changed = TRUE;
|
||
-
|
||
- if (changed)
|
||
+ if (new_color)
|
||
{
|
||
- if (pango_color)
|
||
+ if (color)
|
||
{
|
||
- tmp_color.red = pango_color->red;
|
||
- tmp_color.green = pango_color->green;
|
||
- tmp_color.blue = pango_color->blue;
|
||
+ GdkColor gdk_color;
|
||
+
|
||
+ gdk_color.red = color->red;
|
||
+ gdk_color.green = color->green;
|
||
+ gdk_color.blue = color->blue;
|
||
|
||
- color = &tmp_color;
|
||
+ gdk_gc_set_rgb_fg_color (priv->gc, &gdk_color);
|
||
+
|
||
+ priv->gc_color = *color;
|
||
+ priv->gc_color_set = TRUE;
|
||
}
|
||
else
|
||
- color = NULL;
|
||
+ priv->gc_color_set = FALSE;
|
||
+ }
|
||
|
||
- _gdk_gc_update_context (priv->base_gc,
|
||
- priv->cr,
|
||
- color,
|
||
- priv->stipple[part],
|
||
- priv->gc_changed);
|
||
+ if (new_stipple)
|
||
+ {
|
||
+ if (priv->gc_stipple)
|
||
+ g_object_unref (priv->gc_stipple);
|
||
+
|
||
+ 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;
|
||
}
|
||
|
||
- priv->last_part = part;
|
||
- priv->gc_changed = FALSE;
|
||
+ return priv->gc;
|
||
}
|
||
-
|
||
- return priv->cr;
|
||
}
|
||
|
||
static void
|
||
@@ -225,133 +307,78 @@
|
||
{
|
||
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
|
||
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
|
||
- cairo_t *cr;
|
||
|
||
- cr = get_cairo_context (gdk_renderer,
|
||
- PANGO_RENDER_PART_FOREGROUND);
|
||
+ flush_trapezoids (gdk_renderer);
|
||
|
||
- if (priv->embossed)
|
||
+ if (!priv->in_emboss && priv->embossed)
|
||
{
|
||
- cairo_save (cr);
|
||
- emboss_context (cr);
|
||
- cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
|
||
- pango_cairo_show_glyph_string (cr, font, glyphs);
|
||
- cairo_restore (cr);
|
||
- }
|
||
-
|
||
- cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
|
||
- pango_cairo_show_glyph_string (cr, font, glyphs);
|
||
-}
|
||
-
|
||
-/* 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
|
||
+ PangoMatrix *save_matrix;
|
||
+ PangoColor *save_color;
|
||
|
||
-/* Cut-and-pasted between here and pango/pango/pangocairo-render.c */
|
||
+ 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);
|
||
+ }
|
||
+
|
||
+ gdk_draw_glyphs_transformed (priv->drawable,
|
||
+ get_gc (gdk_renderer, PANGO_RENDER_PART_FOREGROUND),
|
||
+ renderer->matrix, font, x, y, glyphs);
|
||
+}
|
||
+
|
||
+/* Outputs any pending trapezoids, we do this when the part or
|
||
+ * part color changes, when we are about to draw text, etc. */
|
||
static void
|
||
-draw_error_underline (cairo_t *cr,
|
||
- double x,
|
||
- double y,
|
||
- double width,
|
||
- double height)
|
||
-{
|
||
- 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;
|
||
+flush_trapezoids (GdkPangoRenderer *gdk_renderer)
|
||
+{
|
||
+ GdkPangoRendererPrivate *priv = gdk_renderer->priv;
|
||
|
||
- x += (width - width_units * unit_width) / 2;
|
||
- width = width_units * unit_width;
|
||
+ if (!priv->trapezoids || priv->trapezoids->len == 0)
|
||
+ return;
|
||
|
||
- y_top = y;
|
||
- y_bottom = y + height;
|
||
-
|
||
- /* 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 */
|
||
- }
|
||
-
|
||
- /* 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 */
|
||
- }
|
||
+ gdk_draw_trapezoids (priv->drawable,
|
||
+ get_gc (gdk_renderer, priv->trapezoid_part),
|
||
+ (GdkTrapezoid *)priv->trapezoids->data,
|
||
+ priv->trapezoids->len);
|
||
|
||
- cairo_close_path (cr);
|
||
- cairo_fill (cr);
|
||
+ g_array_set_size (priv->trapezoids, 0);
|
||
}
|
||
|
||
+/* 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_rectangle (PangoRenderer *renderer,
|
||
- PangoRenderPart part,
|
||
- int x,
|
||
- int y,
|
||
- int width,
|
||
- int height)
|
||
+gdk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
|
||
+ PangoRenderPart part,
|
||
+ double y1,
|
||
+ double x11,
|
||
+ double x21,
|
||
+ double y2,
|
||
+ double x12,
|
||
+ double x22)
|
||
{
|
||
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
|
||
- GdkPangoRendererPrivate *priv = gdk_renderer->priv;
|
||
- cairo_t *cr;
|
||
-
|
||
- cr = get_cairo_context (gdk_renderer, part);
|
||
-
|
||
- if (priv->embossed && part != PANGO_RENDER_PART_BACKGROUND)
|
||
- {
|
||
- 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);
|
||
+ GdkTrapezoid trap;
|
||
|
||
- cairo_fill (cr);
|
||
- cairo_restore (cr);
|
||
- }
|
||
+ if (!gdk_renderer->priv->trapezoids)
|
||
+ gdk_renderer->priv->trapezoids = g_array_new (FALSE, FALSE,
|
||
+ sizeof (GdkTrapezoid));
|
||
+
|
||
+ if (gdk_renderer->priv->trapezoids->len > 0 &&
|
||
+ gdk_renderer->priv->trapezoid_part != part)
|
||
+ flush_trapezoids (gdk_renderer);
|
||
+
|
||
+ gdk_renderer->priv->trapezoid_part = part;
|
||
+
|
||
+ trap.y1 = y1;
|
||
+ trap.x11 = x11 / 2;
|
||
+ trap.x21 = x21;
|
||
+ trap.y2 = y2;
|
||
+ trap.x12 = x12;
|
||
+ trap.x22 = x22;
|
||
|
||
- cairo_rectangle (cr,
|
||
- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
|
||
- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
|
||
- cairo_fill (cr);
|
||
+ g_array_append_val (gdk_renderer->priv->trapezoids, trap);
|
||
}
|
||
|
||
static void
|
||
@@ -363,23 +390,51 @@
|
||
{
|
||
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
|
||
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
|
||
- cairo_t *cr;
|
||
-
|
||
- cr = get_cairo_context (gdk_renderer, PANGO_RENDER_PART_UNDERLINE);
|
||
-
|
||
- if (priv->embossed)
|
||
+
|
||
+ if (!priv->in_emboss && priv->embossed)
|
||
{
|
||
- 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);
|
||
+ 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);
|
||
}
|
||
|
||
- draw_error_underline (cr,
|
||
- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
|
||
- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
|
||
+ PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_error_underline (renderer,
|
||
+ x, y, width, height);
|
||
+}
|
||
+
|
||
+/* 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,
|
||
+ int x,
|
||
+ int y,
|
||
+ int width,
|
||
+ int height)
|
||
+{
|
||
+ GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
|
||
+ GdkPangoRendererPrivate *priv = gdk_renderer->priv;
|
||
+
|
||
+ if (!priv->in_emboss && 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);
|
||
+ }
|
||
+
|
||
+ PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_rectangle (renderer, part,
|
||
+ x, y, width, height);
|
||
}
|
||
|
||
static void
|
||
@@ -388,8 +443,8 @@
|
||
{
|
||
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
|
||
|
||
- if (gdk_renderer->priv->last_part == part)
|
||
- gdk_renderer->priv->last_part = (PangoRenderPart)-1;
|
||
+ if (part == gdk_renderer->priv->trapezoid_part)
|
||
+ flush_trapezoids (gdk_renderer);
|
||
}
|
||
|
||
static void
|
||
@@ -410,13 +465,8 @@
|
||
{
|
||
GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
|
||
GdkPangoRendererPrivate *priv = gdk_renderer->priv;
|
||
-
|
||
- if (priv->cr)
|
||
- {
|
||
- cairo_destroy (priv->cr);
|
||
- priv->cr = NULL;
|
||
- }
|
||
- priv->last_part = (PangoRenderPart)-1;
|
||
+
|
||
+ flush_trapezoids (gdk_renderer);
|
||
}
|
||
|
||
static void
|
||
@@ -515,7 +565,6 @@
|
||
GDK_TYPE_PANGO_RENDERER,
|
||
GdkPangoRendererPrivate);
|
||
|
||
- renderer->priv->last_part = (PangoRenderPart)-1;
|
||
renderer->priv->gc_changed = TRUE;
|
||
}
|
||
|
||
@@ -527,6 +576,7 @@
|
||
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;
|
||
@@ -647,6 +697,8 @@
|
||
|
||
priv = gdk_renderer->priv;
|
||
|
||
+ flush_trapezoids (gdk_renderer);
|
||
+
|
||
if (priv->drawable != drawable)
|
||
{
|
||
if (priv->drawable)
|
||
@@ -681,6 +733,8 @@
|
||
|
||
priv = gdk_renderer->priv;
|
||
|
||
+ flush_trapezoids (gdk_renderer);
|
||
+
|
||
if (priv->base_gc != gc)
|
||
{
|
||
if (priv->base_gc)
|
||
@@ -689,6 +743,20 @@
|
||
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;
|
||
+ }
|
||
+
|
||
priv->gc_changed = TRUE;
|
||
}
|
||
}
|
||
@@ -1414,50 +1482,5 @@
|
||
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.
|
||
- *
|
||
- * The newly created context will have the default font options
|
||
- * (see #cairo_font_options_t) for the screen; if these options
|
||
- * change it will not be updated. Using gtk_widget_get_pango_context()
|
||
- * is more convenient if you want to keep a context around and track
|
||
- * changes to the screen's font rendering settings.
|
||
- *
|
||
- * Return value: a new #PangoContext for @screen
|
||
- *
|
||
- * Since: 2.2
|
||
- **/
|
||
-PangoContext *
|
||
-gdk_pango_context_get_for_screen (GdkScreen *screen)
|
||
-{
|
||
- PangoFontMap *fontmap;
|
||
- PangoContext *context;
|
||
- const cairo_font_options_t *options;
|
||
- double dpi;
|
||
-
|
||
- g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
|
||
-
|
||
- fontmap = pango_cairo_font_map_get_default ();
|
||
-
|
||
- context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
|
||
-
|
||
- options = gdk_screen_get_font_options (screen);
|
||
- pango_cairo_context_set_font_options (context, options);
|
||
-
|
||
- dpi = gdk_screen_get_resolution (screen);
|
||
- pango_cairo_context_set_resolution (context, dpi);
|
||
-
|
||
- return context;
|
||
-}
|
||
-
|
||
#define __GDK_PANGO_C__
|
||
#include "gdkaliasdef.c"
|
||
Index: gtk+-2.10.6/gdk/gdk.symbols
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/gdk.symbols 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/gdk.symbols 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -861,7 +861,6 @@
|
||
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
|
||
@@ -877,6 +876,12 @@
|
||
#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
|
||
Index: gtk+-2.10.6/gdk/gdkwindow.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/gdkwindow.c 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/gdkwindow.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -1834,9 +1834,14 @@
|
||
}
|
||
else
|
||
{
|
||
- method->cr = cairo_create (paint->surface);
|
||
+ /*method->cr = cairo_create (paint->surface);
|
||
|
||
- gdk_cairo_set_source_color (method->cr, &private->bg_color);
|
||
+ gdk_cairo_set_source_color (method->cr, &private->bg_color);*/
|
||
+ GdkGC *gc = _gdk_drawable_get_scratch_gc (paint->pixmap, FALSE);
|
||
+
|
||
+ gdk_gc_set_foreground (gc, &(private->bg_color));
|
||
+
|
||
+ method->gc = g_object_ref (gc);
|
||
}
|
||
}
|
||
|
||
Index: gtk+-2.10.6/gdk/x11/gdkdisplay-x11.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkdisplay-x11.c 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkdisplay-x11.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -190,7 +190,8 @@
|
||
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,
|
||
&display_x11->xfixes_event_base,
|
||
Index: gtk+-2.10.6/gdk/x11/gdkdisplay-x11.h
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkdisplay-x11.h 2006-10-30 12:58:29.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkdisplay-x11.h 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -78,6 +78,7 @@
|
||
gboolean use_xshm;
|
||
gboolean have_shm_pixmaps;
|
||
GdkTristate have_render;
|
||
+ GdkTristate have_render_with_trapezoids;
|
||
gboolean have_xfixes;
|
||
gint xfixes_event_base;
|
||
|
||
Index: gtk+-2.10.6/gdk/x11/gdkdrawable-x11.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkdrawable-x11.c 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkdrawable-x11.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -26,6 +26,8 @@
|
||
|
||
#include <config.h>
|
||
|
||
+#include <pango/pangoxft.h>
|
||
+
|
||
#include "gdkx.h"
|
||
#include "gdkregion-generic.h"
|
||
|
||
@@ -106,7 +108,21 @@
|
||
GdkGC *gc,
|
||
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,
|
||
@@ -129,6 +145,11 @@
|
||
gint x_dither,
|
||
gint y_dither);
|
||
|
||
+static void gdk_x11_draw_trapezoids (GdkDrawable *drawable,
|
||
+ GdkGC *gc,
|
||
+ GdkTrapezoid *trapezoids,
|
||
+ gint n_trapezoids);
|
||
+
|
||
static cairo_surface_t *gdk_x11_ref_cairo_surface (GdkDrawable *drawable);
|
||
|
||
static void gdk_x11_set_colormap (GdkDrawable *drawable,
|
||
@@ -163,8 +184,11 @@
|
||
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->ref_cairo_surface = gdk_x11_ref_cairo_surface;
|
||
|
||
@@ -327,6 +351,72 @@
|
||
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)
|
||
{
|
||
@@ -393,6 +483,57 @@
|
||
}
|
||
}
|
||
|
||
+static void
|
||
+gdk_x11_drawable_update_xft_clip (GdkDrawable *drawable,
|
||
+ GdkGC *gc)
|
||
+{
|
||
+ XftDraw *xft_draw = gdk_x11_drawable_get_xft_draw (drawable);
|
||
+ GdkRegion *clip_region = _gdk_gc_get_clip_region (gc);
|
||
+
|
||
+ if (gc && clip_region)
|
||
+ {
|
||
+ GdkRegionBox *boxes = clip_region->rects;
|
||
+ gint n_boxes = clip_region->numRects;
|
||
+#if 0 /* Until XftDrawSetClipRectangles is there */
|
||
+ XRectangle *rects = g_new (XRectangle, n_boxes);
|
||
+ int i;
|
||
+
|
||
+ for (i=0; i < n_boxes; i++)
|
||
+ {
|
||
+ rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
|
||
+ rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
|
||
+ 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
|
||
+ }
|
||
+ else
|
||
+ {
|
||
+ XftDrawSetClip (xft_draw, NULL);
|
||
+ }
|
||
+}
|
||
+
|
||
/*****************************************************
|
||
* X11 specific implementations of generic functions *
|
||
*****************************************************/
|
||
@@ -780,6 +921,45 @@
|
||
}
|
||
|
||
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,
|
||
@@ -1444,6 +1624,47 @@
|
||
}
|
||
|
||
static void
|
||
+gdk_x11_draw_trapezoids (GdkDrawable *drawable,
|
||
+ GdkGC *gc,
|
||
+ GdkTrapezoid *trapezoids,
|
||
+ gint n_trapezoids)
|
||
+{
|
||
+ GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
|
||
+ GdkDisplay *display = gdk_screen_get_display (screen);
|
||
+ XTrapezoid *xtrapezoids;
|
||
+ gint i;
|
||
+
|
||
+ if (!_gdk_x11_have_render_with_trapezoids (display))
|
||
+ {
|
||
+ GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper;
|
||
+ GDK_DRAWABLE_CLASS (_gdk_drawable_impl_x11_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);
|
||
+}
|
||
+
|
||
+static void
|
||
gdk_x11_cairo_surface_destroy (void *data)
|
||
{
|
||
GdkDrawableImplX11 *impl = data;
|
||
@@ -1498,5 +1719,89 @@
|
||
return impl->cairo_surface;
|
||
}
|
||
|
||
+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++)
|
||
+ {
|
||
+ 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);
|
||
+ }
|
||
+
|
||
+ gdk_x11_draw_trapezoids (drawable, gc, trapezoids, n_trapezoids);
|
||
+ g_free (trapezoids);
|
||
+
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ 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);
|
||
+}
|
||
+
|
||
+void
|
||
+_gdk_x11_drawable_draw_xft_glyphs (GdkDrawable *drawable,
|
||
+ GdkGC *gc,
|
||
+ XftFont *xft_font,
|
||
+ XftGlyphSpec *glyphs,
|
||
+ gint n_glyphs)
|
||
+{
|
||
+ 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);
|
||
+ }
|
||
+}
|
||
#define __GDK_DRAWABLE_X11_C__
|
||
#include "gdkaliasdef.c"
|
||
Index: gtk+-2.10.6/gdk/x11/gdkdrawable-x11.h
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkdrawable-x11.h 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkdrawable-x11.h 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -33,6 +33,7 @@
|
||
|
||
#include <X11/Xlib.h>
|
||
#include <X11/extensions/Xrender.h>
|
||
+#include <X11/Xft/Xft.h>
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
@@ -68,6 +69,8 @@
|
||
Window xid;
|
||
GdkScreen *screen;
|
||
|
||
+ XftDraw *xft_draw;
|
||
+
|
||
Picture picture;
|
||
cairo_surface_t *cairo_surface;
|
||
};
|
||
@@ -92,7 +95,15 @@
|
||
/* Note that the following take GdkDrawableImplX11, not the wrapper drawable */
|
||
void _gdk_x11_drawable_finish (GdkDrawable *drawable);
|
||
void _gdk_x11_drawable_update_size (GdkDrawable *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);
|
||
G_END_DECLS
|
||
|
||
#endif /* __GDK_DRAWABLE_X11_H__ */
|
||
Index: gtk+-2.10.6/gdk/x11/gdkgc-x11.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkgc-x11.c 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkgc-x11.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -80,7 +80,10 @@
|
||
gdk_gc_x11_finalize (GObject *object)
|
||
{
|
||
GdkGCX11 *x11_gc = GDK_GC_X11 (object);
|
||
-
|
||
+
|
||
+ if (x11_gc->fg_picture != None)
|
||
+ XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture);
|
||
+
|
||
XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc));
|
||
|
||
G_OBJECT_CLASS (_gdk_gc_x11_parent_class)->finalize (object);
|
||
@@ -110,7 +113,7 @@
|
||
|
||
private->dirty_mask = 0;
|
||
private->have_clip_mask = FALSE;
|
||
-
|
||
+
|
||
private->screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
|
||
|
||
private->depth = gdk_drawable_get_depth (drawable);
|
||
@@ -339,6 +342,18 @@
|
||
}
|
||
|
||
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)
|
||
@@ -367,6 +382,29 @@
|
||
x11_gc->have_clip_mask = values->clip_mask != NULL;
|
||
}
|
||
|
||
+ if (values_mask & GDK_GC_BACKGROUND)
|
||
+ {
|
||
+ if (_gdk_gc_get_fill (gc) == GDK_OPAQUE_STIPPLED)
|
||
+ clear_fg_picture (gc);
|
||
+ }
|
||
+
|
||
+ if (values_mask & GDK_GC_FILL)
|
||
+ {
|
||
+ clear_fg_picture (gc);
|
||
+ }
|
||
+
|
||
+ if (values_mask & GDK_GC_STIPPLE)
|
||
+ {
|
||
+ if (_gdk_gc_get_fill (gc) == GDK_STIPPLED || _gdk_gc_get_fill (gc) == GDK_OPAQUE_STIPPLED)
|
||
+ clear_fg_picture (gc);
|
||
+ }
|
||
+
|
||
+ if (values_mask & GDK_GC_TILE)
|
||
+ {
|
||
+ if (_gdk_gc_get_fill (gc) == GDK_TILED)
|
||
+ clear_fg_picture (gc);
|
||
+ }
|
||
+
|
||
gdk_x11_gc_values_to_xvalues (values, values_mask, &xvalues, &xvalues_mask);
|
||
|
||
XChangeGC (GDK_GC_XDISPLAY (gc),
|
||
@@ -642,6 +680,8 @@
|
||
x11_dst_gc->dirty_mask = x11_src_gc->dirty_mask;
|
||
x11_dst_gc->have_clip_region = x11_src_gc->have_clip_region;
|
||
x11_dst_gc->have_clip_mask = x11_src_gc->have_clip_mask;
|
||
+
|
||
+ clear_fg_picture (dst_gc);
|
||
}
|
||
|
||
/**
|
||
@@ -701,5 +741,359 @@
|
||
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 (_gdk_gc_get_tile (gc));
|
||
+ 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 (_gdk_gc_get_tile (gc)),
|
||
+ format,
|
||
+ CPRepeat, &pa);
|
||
+ }
|
||
+
|
||
+ return None;
|
||
+}
|
||
+
|
||
+static Picture
|
||
+make_stipple_picture (GdkGC *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 (_gdk_gc_get_stipple (gc)),
|
||
+ 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)
|
||
+{
|
||
+ GdkColormap *cmap;
|
||
+
|
||
+ cmap = gdk_gc_get_colormap (gc);
|
||
+
|
||
+ if (cmap)
|
||
+ {
|
||
+ GdkColor color;
|
||
+
|
||
+ gdk_colormap_query_color (cmap, _gdk_gc_get_bg_pixel (gc), &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 (_gdk_gc_get_fill (gc))
|
||
+ {
|
||
+ case GDK_SOLID:
|
||
+ break;
|
||
+ case GDK_TILED:
|
||
+ if (_gdk_gc_get_tile (gc))
|
||
+ {
|
||
+ 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 (_gdk_gc_get_stipple (gc))
|
||
+ {
|
||
+ gdk_drawable_get_size (_gdk_gc_get_stipple (gc), &width, &height);
|
||
+ fill = _gdk_gc_get_fill (gc);
|
||
+ }
|
||
+ 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 = _gdk_gc_get_fg_pixel (gc);
|
||
+
|
||
+ 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)
|
||
+{
|
||
+ GdkColormap *cmap;
|
||
+
|
||
+ g_return_if_fail (GDK_IS_GC_X11 (gc));
|
||
+
|
||
+ color->pixel = _gdk_gc_get_fg_pixel (gc);
|
||
+
|
||
+ cmap = gdk_gc_get_colormap (gc);
|
||
+
|
||
+ if (cmap)
|
||
+ gdk_colormap_query_color (cmap, _gdk_gc_get_fg_pixel (gc), color);
|
||
+ else
|
||
+ g_warning ("No colormap in _gdk_windowing_gc_get_foreground");
|
||
+}
|
||
#define __GDK_GC_X11_C__
|
||
#include "gdkaliasdef.c"
|
||
Index: gtk+-2.10.6/gdk/x11/gdkprivate-x11.h
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkprivate-x11.h 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkprivate-x11.h 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -63,6 +63,9 @@
|
||
guint have_clip_region : 1;
|
||
guint have_clip_mask : 1;
|
||
guint depth : 8;
|
||
+
|
||
+ Picture fg_picture;
|
||
+ XRenderColor fg_picture_color;
|
||
};
|
||
|
||
struct _GdkGCX11Class
|
||
@@ -102,6 +105,11 @@
|
||
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,
|
||
Index: gtk+-2.10.6/gdk/x11/gdkwindow-x11.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkwindow-x11.c 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkwindow-x11.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -1114,7 +1114,8 @@
|
||
{
|
||
GdkWindowObject *private = (GdkWindowObject *)window;
|
||
GdkToplevelX11 *toplevel;
|
||
-
|
||
+ GdkDrawableImplX11 *draw_impl;
|
||
+
|
||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||
|
||
_gdk_selection_window_destroyed (window);
|
||
@@ -1126,6 +1127,11 @@
|
||
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);
|
||
+
|
||
_gdk_x11_drawable_finish (private->impl);
|
||
|
||
if (!recursing && !foreign_destroy)
|
||
Index: gtk+-2.10.6/gdk/x11/Makefile.am
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/Makefile.am 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/Makefile.am 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -37,6 +37,7 @@
|
||
gdkinput.c \
|
||
gdkkeys-x11.c \
|
||
gdkmain-x11.c \
|
||
+ gdkpango-x11.c \
|
||
gdkpixmap-x11.c \
|
||
gdkpixmap-x11.h \
|
||
gdkproperty-x11.c \
|
||
Index: gtk+-2.10.6/gtk/gtkcalendar.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gtk/gtkcalendar.c 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gtk/gtkcalendar.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -1821,7 +1821,7 @@
|
||
}
|
||
}
|
||
|
||
-
|
||
+
|
||
/****************************************
|
||
* Repainting *
|
||
****************************************/
|
||
@@ -1831,7 +1831,7 @@
|
||
{
|
||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
|
||
- cairo_t *cr;
|
||
+ GdkGC *gc;
|
||
char buffer[255];
|
||
int x, y;
|
||
gint header_width;
|
||
@@ -1849,7 +1849,7 @@
|
||
else
|
||
year_left = !priv->year_before;
|
||
|
||
- cr = gdk_cairo_create (priv->header_win);
|
||
+ gc = calendar->gc;
|
||
|
||
header_width = widget->allocation.width - 2 * widget->style->xthickness;
|
||
|
||
@@ -1902,9 +1902,9 @@
|
||
- (max_year_width - logical_rect.width)/2);
|
||
|
||
|
||
- gdk_cairo_set_source_color (cr, HEADER_FG_COLOR (GTK_WIDGET (calendar)));
|
||
- cairo_move_to (cr, x, y);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
+ gdk_gc_set_foreground (gc, HEADER_FG_COLOR (GTK_WIDGET (calendar)));
|
||
+ gdk_draw_layout (priv->header_win, gc, x, y, layout);
|
||
+
|
||
|
||
/* Draw month */
|
||
g_snprintf (buffer, sizeof (buffer), "%s", default_monthname[calendar->month]);
|
||
@@ -1924,19 +1924,19 @@
|
||
else
|
||
x = 3 + priv->arrow_width + (max_month_width - logical_rect.width)/2;
|
||
|
||
- cairo_move_to (cr, x, y);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
-
|
||
+ gdk_draw_layout (priv->header_win, gc, x, y, layout);
|
||
+
|
||
+ gdk_gc_set_foreground (gc, BACKGROUND_COLOR (GTK_WIDGET (calendar)));
|
||
+
|
||
g_object_unref (layout);
|
||
- cairo_destroy (cr);
|
||
}
|
||
|
||
static void
|
||
calendar_paint_day_names (GtkCalendar *calendar)
|
||
{
|
||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||
+ GdkGC *gc;
|
||
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
|
||
- cairo_t *cr;
|
||
char buffer[255];
|
||
int day,i;
|
||
int day_width, cal_width;
|
||
@@ -1946,8 +1946,7 @@
|
||
gint focus_padding;
|
||
gint focus_width;
|
||
|
||
- cr = gdk_cairo_create (priv->day_name_win);
|
||
-
|
||
+ gc = calendar->gc;
|
||
gtk_widget_style_get (GTK_WIDGET (widget),
|
||
"focus-line-width", &focus_width,
|
||
"focus-padding", &focus_padding,
|
||
@@ -1961,22 +1960,19 @@
|
||
* Draw rectangles as inverted background for the labels.
|
||
*/
|
||
|
||
- gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget));
|
||
- cairo_rectangle (cr,
|
||
- CALENDAR_MARGIN, CALENDAR_MARGIN,
|
||
- cal_width-CALENDAR_MARGIN * 2,
|
||
- priv->day_name_h - CALENDAR_MARGIN);
|
||
- cairo_fill (cr);
|
||
-
|
||
+ gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (widget));
|
||
+ gdk_draw_rectangle (priv->day_name_win, gc, TRUE,
|
||
+ CALENDAR_MARGIN, CALENDAR_MARGIN,
|
||
+ cal_width-CALENDAR_MARGIN * 2,
|
||
+ priv->day_name_h - CALENDAR_MARGIN);
|
||
+
|
||
if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
|
||
- {
|
||
- cairo_rectangle (cr,
|
||
- CALENDAR_MARGIN,
|
||
- priv->day_name_h - CALENDAR_YSEP,
|
||
- priv->week_width - CALENDAR_YSEP - CALENDAR_MARGIN,
|
||
- CALENDAR_YSEP);
|
||
- cairo_fill (cr);
|
||
- }
|
||
+ gdk_draw_rectangle (priv->day_name_win, gc, TRUE,
|
||
+ CALENDAR_MARGIN,
|
||
+ priv->day_name_h - CALENDAR_YSEP,
|
||
+ priv->week_width - CALENDAR_YSEP - CALENDAR_MARGIN,
|
||
+ CALENDAR_YSEP);
|
||
+
|
||
|
||
/*
|
||
* Write the labels
|
||
@@ -1984,7 +1980,7 @@
|
||
|
||
layout = gtk_widget_create_pango_layout (widget, NULL);
|
||
|
||
- gdk_cairo_set_source_color (cr, SELECTED_FG_COLOR (widget));
|
||
+ gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (widget));
|
||
for (i = 0; i < 7; i++)
|
||
{
|
||
if (gtk_widget_get_direction (GTK_WIDGET (calendar)) == GTK_TEXT_DIR_RTL)
|
||
@@ -1997,19 +1993,18 @@
|
||
pango_layout_set_text (layout, buffer, -1);
|
||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||
|
||
- cairo_move_to (cr,
|
||
- (CALENDAR_MARGIN +
|
||
- + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
|
||
- (priv->week_width + (priv->week_width ? CALENDAR_XSEP : 0))
|
||
- : 0)
|
||
- + day_wid_sep * i
|
||
- + (day_width - logical_rect.width)/2),
|
||
- CALENDAR_MARGIN + focus_width + focus_padding + logical_rect.y);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
+ gdk_draw_layout (priv->day_name_win, gc,
|
||
+ (CALENDAR_MARGIN +
|
||
+ + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
|
||
+ (priv->week_width + (priv->week_width ? CALENDAR_XSEP : 0))
|
||
+ : 0)
|
||
+ + day_wid_sep * i
|
||
+ + (day_width - logical_rect.width)/2),
|
||
+ CALENDAR_MARGIN + focus_width + focus_padding + logical_rect.y,
|
||
+ layout);
|
||
}
|
||
|
||
g_object_unref (layout);
|
||
- cairo_destroy (cr);
|
||
}
|
||
|
||
static void
|
||
@@ -2017,7 +2012,7 @@
|
||
{
|
||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
|
||
- cairo_t *cr;
|
||
+ GdkGC *gc;
|
||
gint row, week = 0, year;
|
||
gint x_loc;
|
||
char buffer[32];
|
||
@@ -2027,7 +2022,7 @@
|
||
gint focus_padding;
|
||
gint focus_width;
|
||
|
||
- cr = gdk_cairo_create (priv->week_win);
|
||
+ gc = calendar->gc;
|
||
|
||
gtk_widget_style_get (GTK_WIDGET (widget),
|
||
"focus-line-width", &focus_width,
|
||
@@ -2038,20 +2033,20 @@
|
||
* Draw a rectangle as inverted background for the labels.
|
||
*/
|
||
|
||
- gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget));
|
||
+ gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (widget));
|
||
if (priv->day_name_win)
|
||
- cairo_rectangle (cr,
|
||
- CALENDAR_MARGIN,
|
||
- 0,
|
||
- priv->week_width - CALENDAR_MARGIN,
|
||
- priv->main_h - CALENDAR_MARGIN);
|
||
+ gdk_draw_rectangle (priv->week_win, gc, TRUE,
|
||
+ CALENDAR_MARGIN,
|
||
+ 0,
|
||
+ priv->week_width - CALENDAR_MARGIN,
|
||
+ priv->main_h - CALENDAR_MARGIN);
|
||
else
|
||
- cairo_rectangle (cr,
|
||
- CALENDAR_MARGIN,
|
||
- CALENDAR_MARGIN,
|
||
- priv->week_width - CALENDAR_MARGIN,
|
||
- priv->main_h - 2 * CALENDAR_MARGIN);
|
||
- cairo_fill (cr);
|
||
+ gdk_draw_rectangle (priv->week_win, gc, TRUE,
|
||
+ CALENDAR_MARGIN,
|
||
+ CALENDAR_MARGIN,
|
||
+ priv->week_width - CALENDAR_MARGIN,
|
||
+ priv->main_h - 2 * CALENDAR_MARGIN);
|
||
+
|
||
|
||
/*
|
||
* Write the labels
|
||
@@ -2059,7 +2054,7 @@
|
||
|
||
layout = gtk_widget_create_pango_layout (widget, NULL);
|
||
|
||
- gdk_cairo_set_source_color (cr, SELECTED_FG_COLOR (widget));
|
||
+ gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (widget));
|
||
day_height = calendar_row_height (calendar);
|
||
for (row = 0; row < 6; row++)
|
||
{
|
||
@@ -2095,12 +2090,10 @@
|
||
- logical_rect.width
|
||
- CALENDAR_XSEP - focus_padding - focus_width);
|
||
|
||
- cairo_move_to (cr, x_loc, y_loc);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
+ gdk_draw_layout (priv->week_win, gc, x_loc, y_loc, layout);
|
||
}
|
||
|
||
g_object_unref (layout);
|
||
- cairo_destroy (cr);
|
||
}
|
||
|
||
static void
|
||
@@ -2149,7 +2142,7 @@
|
||
{
|
||
GtkWidget *widget = GTK_WIDGET (calendar);
|
||
GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
|
||
- cairo_t *cr;
|
||
+ GdkGC *gc;
|
||
GdkColor *text_color;
|
||
gchar buffer[32];
|
||
gint day;
|
||
@@ -2162,7 +2155,7 @@
|
||
g_return_if_fail (row < 6);
|
||
g_return_if_fail (col < 7);
|
||
|
||
- cr = gdk_cairo_create (priv->main_win);
|
||
+ gc = calendar->gc;
|
||
|
||
day = calendar->day[row][col];
|
||
|
||
@@ -2170,11 +2163,11 @@
|
||
|
||
if (calendar->day_month[row][col] == MONTH_PREV)
|
||
{
|
||
- text_color = PREV_MONTH_COLOR (widget);
|
||
+ gdk_gc_set_foreground (gc, PREV_MONTH_COLOR (GTK_WIDGET (calendar)));
|
||
}
|
||
else if (calendar->day_month[row][col] == MONTH_NEXT)
|
||
{
|
||
- text_color = NEXT_MONTH_COLOR (widget);
|
||
+ gdk_gc_set_foreground (gc, NEXT_MONTH_COLOR (GTK_WIDGET (calendar)));
|
||
}
|
||
else
|
||
{
|
||
@@ -2188,16 +2181,16 @@
|
||
#endif
|
||
if (calendar->selected_day == day)
|
||
{
|
||
- gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget));
|
||
- gdk_cairo_rectangle (cr, &day_rect);
|
||
- cairo_fill (cr);
|
||
+ gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (GTK_WIDGET (calendar)));
|
||
+ gdk_draw_rectangle (priv->main_win, gc, TRUE, day_rect.x, day_rect.y,
|
||
+ day_rect.width, day_rect.height);
|
||
}
|
||
if (calendar->selected_day == day)
|
||
- text_color = SELECTED_FG_COLOR (widget);
|
||
+ gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (GTK_WIDGET (calendar)));
|
||
else if (calendar->marked_date[day-1])
|
||
- text_color = MARKED_COLOR (widget);
|
||
+ gdk_gc_set_foreground (gc, MARKED_COLOR (GTK_WIDGET (calendar)));
|
||
else
|
||
- text_color = NORMAL_DAY_COLOR (widget);
|
||
+ gdk_gc_set_foreground (gc, NORMAL_DAY_COLOR (GTK_WIDGET (calendar)));
|
||
}
|
||
|
||
/* Translators: this defines whether the day numbers should use
|
||
@@ -2219,16 +2212,13 @@
|
||
x_loc -= logical_rect.width;
|
||
y_loc = day_rect.y + (day_rect.height - logical_rect.height) / 2;
|
||
|
||
- gdk_cairo_set_source_color (cr, text_color);
|
||
- cairo_move_to (cr, x_loc, y_loc);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
+ gdk_draw_layout (priv->main_win, gc,
|
||
+ x_loc, y_loc, layout);
|
||
|
||
if (calendar->marked_date[day-1]
|
||
&& calendar->day_month[row][col] == MONTH_CURRENT)
|
||
- {
|
||
- cairo_move_to (cr, x_loc - 1, y_loc);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
- }
|
||
+ gdk_draw_layout (priv->main_win, gc,
|
||
+ x_loc-1, y_loc, layout);
|
||
|
||
if (GTK_WIDGET_HAS_FOCUS (calendar)
|
||
&& calendar->focus_row == row && calendar->focus_col == col)
|
||
@@ -2253,7 +2243,6 @@
|
||
}
|
||
|
||
g_object_unref (layout);
|
||
- cairo_destroy (cr);
|
||
}
|
||
|
||
static void
|
||
Index: gtk+-2.10.6/gtk/gtkentry.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gtk/gtkentry.c 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gtk/gtkentry.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -3333,7 +3333,6 @@
|
||
if (GTK_WIDGET_DRAWABLE (entry))
|
||
{
|
||
PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
|
||
- cairo_t *cr;
|
||
gint x, y;
|
||
gint start_pos, end_pos;
|
||
|
||
@@ -3341,56 +3340,60 @@
|
||
|
||
get_layout_position (entry, &x, &y);
|
||
|
||
- cr = gdk_cairo_create (entry->text_area);
|
||
-
|
||
- cairo_move_to (cr, x, y);
|
||
- gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
-
|
||
+ gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
|
||
+ x, y,
|
||
+ layout);
|
||
+
|
||
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
|
||
{
|
||
gint *ranges;
|
||
gint n_ranges, i;
|
||
PangoRectangle logical_rect;
|
||
- GdkColor *selection_color, *text_color;
|
||
+ GdkGC *selection_gc, *text_gc;
|
||
GtkBorder inner_border;
|
||
-
|
||
+ GdkRegion *clip_region;
|
||
+
|
||
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||
gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
|
||
|
||
if (GTK_WIDGET_HAS_FOCUS (entry))
|
||
{
|
||
- selection_color = &widget->style->base [GTK_STATE_SELECTED];
|
||
- text_color = &widget->style->text [GTK_STATE_SELECTED];
|
||
+ selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
|
||
+ text_gc = widget->style->text_gc [GTK_STATE_SELECTED];
|
||
}
|
||
else
|
||
{
|
||
- selection_color = &widget->style->base [GTK_STATE_ACTIVE];
|
||
- text_color = &widget->style->text [GTK_STATE_ACTIVE];
|
||
+ selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE];
|
||
+ text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
|
||
}
|
||
-
|
||
+
|
||
+ clip_region = gdk_region_new ();
|
||
_gtk_entry_effective_inner_border (entry, &inner_border);
|
||
|
||
for (i = 0; i < n_ranges; ++i)
|
||
- cairo_rectangle (cr,
|
||
- inner_border.left - entry->scroll_offset + ranges[2 * i],
|
||
- y,
|
||
- ranges[2 * i + 1],
|
||
- logical_rect.height);
|
||
+ {
|
||
+ GdkRectangle rect;
|
||
|
||
- cairo_clip (cr);
|
||
-
|
||
- gdk_cairo_set_source_color (cr, selection_color);
|
||
- cairo_paint (cr);
|
||
+ rect.x = inner_border.left - entry->scroll_offset + ranges[2 * i];
|
||
+ rect.y = y;
|
||
+ rect.width = ranges[2 * i + 1];
|
||
+ rect.height = logical_rect.height;
|
||
+
|
||
+ gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
|
||
+ rect.x, rect.y, rect.width, rect.height);
|
||
|
||
- cairo_move_to (cr, x, y);
|
||
- gdk_cairo_set_source_color (cr, text_color);
|
||
- pango_cairo_show_layout (cr, layout);
|
||
+ gdk_region_union_with_rect (clip_region, &rect);
|
||
+ }
|
||
|
||
+ gdk_gc_set_clip_region (text_gc, clip_region);
|
||
+ gdk_draw_layout (entry->text_area, text_gc,
|
||
+ x, y,
|
||
+ layout);
|
||
+ gdk_gc_set_clip_region (text_gc, NULL);
|
||
+
|
||
+ gdk_region_destroy (clip_region);
|
||
g_free (ranges);
|
||
}
|
||
-
|
||
- cairo_destroy (cr);
|
||
}
|
||
}
|
||
|
||
Index: gtk+-2.10.6/gtk/gtkwidget.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gtk/gtkwidget.c 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gtk/gtkwidget.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -5445,7 +5445,8 @@
|
||
GdkScreen *screen;
|
||
|
||
update_pango_context (widget, context);
|
||
-
|
||
+/* TODO: Figure out the proper way to handle this in a pangoxft setting
|
||
+
|
||
screen = gtk_widget_get_screen_unchecked (widget);
|
||
if (screen)
|
||
{
|
||
@@ -5453,7 +5454,7 @@
|
||
gdk_screen_get_resolution (screen));
|
||
pango_cairo_context_set_font_options (context,
|
||
gdk_screen_get_font_options (screen));
|
||
- }
|
||
+ }*/
|
||
}
|
||
}
|
||
|
||
Index: gtk+-2.10.6/gdk/x11/gdkpango-x11.c
|
||
===================================================================
|
||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkpango-x11.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -0,0 +1,174 @@
|
||
+/* 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"
|
||
Index: gtk+-2.10.6/gdk/x11/gdkpixmap-x11.c
|
||
===================================================================
|
||
--- gtk+-2.10.6.orig/gdk/x11/gdkpixmap-x11.c 2006-10-30 12:58:30.000000000 +0000
|
||
+++ gtk+-2.10.6/gdk/x11/gdkpixmap-x11.c 2006-10-30 12:59:30.000000000 +0000
|
||
@@ -119,6 +119,9 @@
|
||
{
|
||
GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (impl);
|
||
|
||
+ if (draw_impl->xft_draw)
|
||
+ XftDrawDestroy (draw_impl->xft_draw);
|
||
+
|
||
_gdk_x11_drawable_finish (GDK_DRAWABLE (draw_impl));
|
||
}
|
||
|
||
--- gtk+-2.10.6.orig/gtk/gtkcalendar.c.orig 2006-11-14 14:39:34.000000000 -0800
|
||
+++ gtk+-2.10.6/gtk/gtkcalendar.c 2006-11-14 14:37:34.000000000 -0800
|
||
@@ -1495,6 +1495,10 @@ gtk_calendar_realize (GtkWidget *widget)
|
||
BACKGROUND_COLOR ( GTK_WIDGET ( calendar)));
|
||
gdk_window_show (priv->main_win);
|
||
gdk_window_set_user_data (priv->main_win, widget);
|
||
+
|
||
+ /* Set widgets gc */
|
||
+ calendar->gc = gdk_gc_new (widget->window);
|
||
+
|
||
gdk_window_set_background (widget->window, BACKGROUND_COLOR (widget));
|
||
gdk_window_show (widget->window);
|
||
gdk_window_set_user_data (widget->window, widget);
|