summaryrefslogtreecommitdiff
path: root/gdk
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 /gdk
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.
Diffstat (limited to 'gdk')
-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
21 files changed, 674 insertions, 1592 deletions
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 &&