]> Pileus Git - ~andy/gtk/blob - gdk/gdkdraw.c
API: remove gdk_draw_arc()
[~andy/gtk] / gdk / gdkdraw.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28 #include <math.h>
29 #include <pango/pangocairo.h>
30 #include <gdk-pixbuf/gdk-pixbuf.h>
31 #include "gdkcairo.h"
32 #include "gdkdrawable.h"
33 #include "gdkinternals.h"
34 #include "gdkwindow.h"
35 #include "gdkscreen.h"
36 #include "gdkpixbuf.h"
37
38
39 static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable  *drawable,
40                                                               gint          x,
41                                                               gint          y,
42                                                               gint          width,
43                                                               gint          height,
44                                                               gint         *composite_x_offset,
45                                                               gint         *composite_y_offset);
46 static cairo_region_t *  gdk_drawable_real_get_visible_region     (GdkDrawable  *drawable);
47 static void         gdk_drawable_real_draw_drawable          (GdkDrawable  *drawable,
48                                                               GdkGC        *gc,
49                                                               GdkDrawable  *src,
50                                                               gint          xsrc,
51                                                               gint          ysrc,
52                                                               gint          xdest,
53                                                               gint          ydest,
54                                                               gint          width,
55                                                               gint          height);
56      
57
58 G_DEFINE_ABSTRACT_TYPE (GdkDrawable, gdk_drawable, G_TYPE_OBJECT)
59
60 static void
61 gdk_drawable_class_init (GdkDrawableClass *klass)
62 {
63   klass->get_composite_drawable = gdk_drawable_real_get_composite_drawable;
64   /* Default implementation for clip and visible region is the same */
65   klass->get_clip_region = gdk_drawable_real_get_visible_region;
66   klass->get_visible_region = gdk_drawable_real_get_visible_region;
67   klass->draw_drawable = gdk_drawable_real_draw_drawable;
68 }
69
70 static void
71 gdk_drawable_init (GdkDrawable *drawable)
72 {
73 }
74
75 /* Manipulation of drawables
76  */
77
78 /**
79  * gdk_drawable_get_size:
80  * @drawable: a #GdkDrawable
81  * @width: (out) (allow-none): location to store drawable's width, or %NULL
82  * @height: (out) (allow-none): location to store drawable's height, or %NULL
83  *
84  * Fills *@width and *@height with the size of @drawable.
85  * @width or @height can be %NULL if you only want the other one.
86  *
87  * On the X11 platform, if @drawable is a #GdkWindow, the returned
88  * size is the size reported in the most-recently-processed configure
89  * event, rather than the current size on the X server.
90  * 
91  **/
92 void
93 gdk_drawable_get_size (GdkDrawable *drawable,
94                        gint        *width,
95                        gint        *height)
96 {
97   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
98
99   GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height);  
100 }
101
102 /**
103  * gdk_drawable_get_visual:
104  * @drawable: a #GdkDrawable
105  * 
106  * Gets the #GdkVisual describing the pixel format of @drawable.
107  * 
108  * Return value: a #GdkVisual
109  **/
110 GdkVisual*
111 gdk_drawable_get_visual (GdkDrawable *drawable)
112 {
113   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
114   
115   return GDK_DRAWABLE_GET_CLASS (drawable)->get_visual (drawable);
116 }
117
118 /**
119  * gdk_drawable_get_depth:
120  * @drawable: a #GdkDrawable
121  * 
122  * Obtains the bit depth of the drawable, that is, the number of bits
123  * that make up a pixel in the drawable's visual. Examples are 8 bits
124  * per pixel, 24 bits per pixel, etc.
125  * 
126  * Return value: number of bits per pixel
127  **/
128 gint
129 gdk_drawable_get_depth (GdkDrawable *drawable)
130 {
131   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), 0);
132
133   return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable);
134 }
135 /**
136  * gdk_drawable_get_screen:
137  * @drawable: a #GdkDrawable
138  * 
139  * Gets the #GdkScreen associated with a #GdkDrawable.
140  * 
141  * Return value: the #GdkScreen associated with @drawable
142  *
143  * Since: 2.2
144  **/
145 GdkScreen*
146 gdk_drawable_get_screen(GdkDrawable *drawable)
147 {
148   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
149
150   return GDK_DRAWABLE_GET_CLASS (drawable)->get_screen (drawable);
151 }
152
153 /**
154  * gdk_drawable_get_display:
155  * @drawable: a #GdkDrawable
156  * 
157  * Gets the #GdkDisplay associated with a #GdkDrawable.
158  * 
159  * Return value: the #GdkDisplay associated with @drawable
160  *
161  * Since: 2.2
162  **/
163 GdkDisplay*
164 gdk_drawable_get_display (GdkDrawable *drawable)
165 {
166   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
167   
168   return gdk_screen_get_display (gdk_drawable_get_screen (drawable));
169 }
170         
171 /**
172  * gdk_drawable_set_colormap:
173  * @drawable: a #GdkDrawable
174  * @colormap: a #GdkColormap
175  *
176  * Sets the colormap associated with @drawable. Normally this will
177  * happen automatically when the drawable is created; you only need to
178  * use this function if the drawable-creating function did not have a
179  * way to determine the colormap, and you then use drawable operations
180  * that require a colormap. The colormap for all drawables and
181  * graphics contexts you intend to use together should match. i.e.
182  * when using a #GdkGC to draw to a drawable, or copying one drawable
183  * to another, the colormaps should match.
184  * 
185  **/
186 void
187 gdk_drawable_set_colormap (GdkDrawable *drawable,
188                            GdkColormap *cmap)
189 {
190   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
191   g_return_if_fail (cmap == NULL || gdk_drawable_get_depth (drawable)
192                     == cmap->visual->depth);
193
194   GDK_DRAWABLE_GET_CLASS (drawable)->set_colormap (drawable, cmap);
195 }
196
197 /**
198  * gdk_drawable_get_colormap:
199  * @drawable: a #GdkDrawable
200  * 
201  * Gets the colormap for @drawable, if one is set; returns
202  * %NULL otherwise.
203  * 
204  * Return value: the colormap, or %NULL
205  **/
206 GdkColormap*
207 gdk_drawable_get_colormap (GdkDrawable *drawable)
208 {
209   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
210
211   return GDK_DRAWABLE_GET_CLASS (drawable)->get_colormap (drawable);
212 }
213
214 /* Drawing
215  */
216
217 /**
218  * gdk_draw_point:
219  * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
220  * @gc: a #GdkGC.
221  * @x: the x coordinate of the point.
222  * @y: the y coordinate of the point.
223  * 
224  * Draws a point, using the foreground color and other attributes of 
225  * the #GdkGC.
226  **/
227 void
228 gdk_draw_point (GdkDrawable *drawable,
229                 GdkGC       *gc,
230                 gint         x,
231                 gint         y)
232 {
233   GdkPoint point;
234
235   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
236   g_return_if_fail (GDK_IS_GC (gc));
237
238   point.x = x;
239   point.y = y;
240   
241   GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, &point, 1);
242 }
243
244 /**
245  * gdk_draw_line:
246  * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). 
247  * @gc: a #GdkGC.
248  * @x1_: the x coordinate of the start point.
249  * @y1_: the y coordinate of the start point.
250  * @x2_: the x coordinate of the end point.
251  * @y2_: the y coordinate of the end point.
252  * 
253  * Draws a line, using the foreground color and other attributes of 
254  * the #GdkGC.
255  **/
256 void
257 gdk_draw_line (GdkDrawable *drawable,
258                GdkGC       *gc,
259                gint         x1,
260                gint         y1,
261                gint         x2,
262                gint         y2)
263 {
264   GdkSegment segment;
265
266   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
267   g_return_if_fail (GDK_IS_GC (gc));
268
269   segment.x1 = x1;
270   segment.y1 = y1;
271   segment.x2 = x2;
272   segment.y2 = y2;
273   GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, &segment, 1);
274 }
275
276 /**
277  * gdk_draw_rectangle:
278  * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
279  * @gc: a #GdkGC.
280  * @filled: %TRUE if the rectangle should be filled.
281  * @x: the x coordinate of the left edge of the rectangle.
282  * @y: the y coordinate of the top edge of the rectangle.
283  * @width: the width of the rectangle.
284  * @height: the height of the rectangle.
285  * 
286  * Draws a rectangular outline or filled rectangle, using the foreground color
287  * and other attributes of the #GdkGC.
288  *
289  * A rectangle drawn filled is 1 pixel smaller in both dimensions than a 
290  * rectangle outlined. Calling 
291  * <literal>gdk_draw_rectangle (window, gc, TRUE, 0, 0, 20, 20)</literal> 
292  * results in a filled rectangle 20 pixels wide and 20 pixels high. Calling
293  * <literal>gdk_draw_rectangle (window, gc, FALSE, 0, 0, 20, 20)</literal> 
294  * results in an outlined rectangle with corners at (0, 0), (0, 20), (20, 20),
295  * and (20, 0), which makes it 21 pixels wide and 21 pixels high.
296  **/
297 void
298 gdk_draw_rectangle (GdkDrawable *drawable,
299                     GdkGC       *gc,
300                     gboolean     filled,
301                     gint         x,
302                     gint         y,
303                     gint         width,
304                     gint         height)
305 {  
306   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
307   g_return_if_fail (GDK_IS_GC (gc));
308
309   if (width < 0 || height < 0)
310     {
311       gint real_width;
312       gint real_height;
313       
314       gdk_drawable_get_size (drawable, &real_width, &real_height);
315
316       if (width < 0)
317         width = real_width;
318       if (height < 0)
319         height = real_height;
320     }
321
322   GDK_DRAWABLE_GET_CLASS (drawable)->draw_rectangle (drawable, gc, filled, x, y,
323                                                      width, height);
324 }
325
326 /**
327  * gdk_draw_polygon:
328  * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
329  * @gc: a #GdkGC.
330  * @filled: %TRUE if the polygon should be filled. The polygon is closed
331  *     automatically, connecting the last point to the first point if 
332  *     necessary.
333  * @points: an array of #GdkPoint structures specifying the points making 
334  *     up the polygon.
335  * @n_points: the number of points.
336  * 
337  * Draws an outlined or filled polygon.
338  **/
339 void
340 gdk_draw_polygon (GdkDrawable    *drawable,
341                   GdkGC          *gc,
342                   gboolean        filled,
343                   const GdkPoint *points,
344                   gint            n_points)
345 {
346   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
347   g_return_if_fail (GDK_IS_GC (gc));
348
349   GDK_DRAWABLE_GET_CLASS (drawable)->draw_polygon (drawable, gc, filled,
350                                                    (GdkPoint *) points,
351                                                    n_points);
352 }
353
354 /**
355  * gdk_draw_drawable:
356  * @drawable: a #GdkDrawable
357  * @gc: a #GdkGC sharing the drawable's visual and colormap
358  * @src: the source #GdkDrawable, which may be the same as @drawable
359  * @xsrc: X position in @src of rectangle to draw
360  * @ysrc: Y position in @src of rectangle to draw
361  * @xdest: X position in @drawable where the rectangle should be drawn
362  * @ydest: Y position in @drawable where the rectangle should be drawn
363  * @width: width of rectangle to draw, or -1 for entire @src width
364  * @height: height of rectangle to draw, or -1 for entire @src height
365  *
366  * Copies the @width x @height region of @src at coordinates (@xsrc,
367  * @ysrc) to coordinates (@xdest, @ydest) in @drawable.
368  * @width and/or @height may be given as -1, in which case the entire
369  * @src drawable will be copied.
370  *
371  * Most fields in @gc are not used for this operation, but notably the
372  * clip mask or clip region will be honored.
373  *
374  * The source and destination drawables must have the same visual and
375  * colormap, or errors will result. (On X11, failure to match
376  * visual/colormap results in a BadMatch error from the X server.)
377  * A common cause of this problem is an attempt to draw a bitmap to
378  * a color drawable. The way to draw a bitmap is to set the bitmap as 
379  * the stipple on the #GdkGC, set the fill mode to %GDK_STIPPLED, and 
380  * then draw the rectangle.
381  **/
382 void
383 gdk_draw_drawable (GdkDrawable *drawable,
384                    GdkGC       *gc,
385                    GdkDrawable *src,
386                    gint         xsrc,
387                    gint         ysrc,
388                    gint         xdest,
389                    gint         ydest,
390                    gint         width,
391                    gint         height)
392 {
393   GdkDrawable *composite;
394   gint composite_x_offset = 0;
395   gint composite_y_offset = 0;
396
397   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
398   g_return_if_fail (GDK_IS_DRAWABLE (src));
399   g_return_if_fail (GDK_IS_GC (gc));
400
401   if (width < 0 || height < 0)
402     {
403       gint real_width;
404       gint real_height;
405       
406       gdk_drawable_get_size (src, &real_width, &real_height);
407
408       if (width < 0)
409         width = real_width;
410       if (height < 0)
411         height = real_height;
412     }
413
414
415   composite =
416     GDK_DRAWABLE_GET_CLASS (src)->get_composite_drawable (src,
417                                                           xsrc, ysrc,
418                                                           width, height,
419                                                           &composite_x_offset,
420                                                           &composite_y_offset);
421
422   /* TODO: For non-native windows this may copy stuff from other overlapping
423      windows. We should clip that and (for windows with bg != None) clear that
424      area in the destination instead. */
425
426   if (GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src)
427     GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable, gc,
428                                                                composite,
429                                                                xsrc - composite_x_offset,
430                                                                ysrc - composite_y_offset,
431                                                                xdest, ydest,
432                                                                width, height,
433                                                                src);
434   else /* backwards compat for old out-of-tree implementations of GdkDrawable (are there any?) */
435     GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc,
436                                                       composite,
437                                                       xsrc - composite_x_offset,
438                                                       ysrc - composite_y_offset,
439                                                       xdest, ydest,
440                                                       width, height);
441
442   g_object_unref (composite);
443 }
444
445 /**
446  * gdk_draw_points:
447  * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
448  * @gc: a #GdkGC.
449  * @points: an array of #GdkPoint structures.
450  * @n_points: the number of points to be drawn.
451  * 
452  * Draws a number of points, using the foreground color and other 
453  * attributes of the #GdkGC.
454  **/
455 void
456 gdk_draw_points (GdkDrawable    *drawable,
457                  GdkGC          *gc,
458                  const GdkPoint *points,
459                  gint            n_points)
460 {
461   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
462   g_return_if_fail ((points != NULL) && (n_points > 0));
463   g_return_if_fail (GDK_IS_GC (gc));
464   g_return_if_fail (n_points >= 0);
465
466   if (n_points == 0)
467     return;
468
469   GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc,
470                                                   (GdkPoint *) points, n_points);
471 }
472
473 /**
474  * gdk_draw_segments:
475  * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
476  * @gc: a #GdkGC.
477  * @segs: an array of #GdkSegment structures specifying the start and 
478  *   end points of the lines to be drawn.
479  * @n_segs: the number of line segments to draw, i.e. the size of the 
480  *   @segs array.
481  * 
482  * Draws a number of unconnected lines.
483  **/
484 void
485 gdk_draw_segments (GdkDrawable      *drawable,
486                    GdkGC            *gc,
487                    const GdkSegment *segs,
488                    gint              n_segs)
489 {
490   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
491
492   if (n_segs == 0)
493     return;
494
495   g_return_if_fail (segs != NULL);
496   g_return_if_fail (GDK_IS_GC (gc));
497   g_return_if_fail (n_segs >= 0);
498
499   GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc,
500                                                     (GdkSegment *) segs, n_segs);
501 }
502
503 /**
504  * gdk_draw_lines:
505  * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
506  * @gc: a #GdkGC.
507  * @points: an array of #GdkPoint structures specifying the endpoints of the
508  * @n_points: the size of the @points array.
509  * 
510  * Draws a series of lines connecting the given points.
511  * The way in which joins between lines are draw is determined by the
512  * #GdkCapStyle value in the #GdkGC. This can be set with
513  * gdk_gc_set_line_attributes().
514  **/
515 void
516 gdk_draw_lines (GdkDrawable    *drawable,
517                 GdkGC          *gc,
518                 const GdkPoint *points,
519                 gint            n_points)
520 {
521   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
522   g_return_if_fail (points != NULL);
523   g_return_if_fail (GDK_IS_GC (gc));
524   g_return_if_fail (n_points >= 0);
525
526   if (n_points == 0)
527     return;
528
529   GDK_DRAWABLE_GET_CLASS (drawable)->draw_lines (drawable, gc,
530                                                  (GdkPoint *) points, n_points);
531 }
532
533 static void
534 real_draw_glyphs (GdkDrawable       *drawable,
535                   GdkGC             *gc,
536                   const PangoMatrix *matrix,
537                   PangoFont         *font,
538                   gdouble            x,
539                   gdouble            y,
540                   PangoGlyphString  *glyphs)
541 {
542   cairo_t *cr;
543
544   cr = gdk_cairo_create (drawable);
545   _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable);
546
547   if (matrix)
548     {
549       cairo_matrix_t cairo_matrix;
550
551       cairo_matrix.xx = matrix->xx;
552       cairo_matrix.yx = matrix->yx;
553       cairo_matrix.xy = matrix->xy;
554       cairo_matrix.yy = matrix->yy;
555       cairo_matrix.x0 = matrix->x0;
556       cairo_matrix.y0 = matrix->y0;
557       
558       cairo_set_matrix (cr, &cairo_matrix);
559     }
560
561   cairo_move_to (cr, x, y);
562   pango_cairo_show_glyph_string (cr, font, glyphs);
563
564   cairo_destroy (cr);
565 }
566
567 /**
568  * gdk_draw_glyphs:
569  * @drawable: a #GdkDrawable
570  * @gc: a #GdkGC
571  * @font: font to be used
572  * @x: X coordinate of baseline origin
573  * @y: Y coordinate of baseline origin
574  * @glyphs: the glyph string to draw
575  *
576  * This is a low-level function; 99% of text rendering should be done
577  * using gdk_draw_layout() instead.
578  *
579  * A glyph is a single image in a font. This function draws a sequence of
580  * glyphs.  To obtain a sequence of glyphs you have to understand a
581  * lot about internationalized text handling, which you don't want to
582  * understand; thus, use gdk_draw_layout() instead of this function,
583  * gdk_draw_layout() handles the details.
584  * 
585  **/
586 void
587 gdk_draw_glyphs (GdkDrawable      *drawable,
588                  GdkGC            *gc,
589                  PangoFont        *font,
590                  gint              x,
591                  gint              y,
592                  PangoGlyphString *glyphs)
593 {
594   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
595   g_return_if_fail (GDK_IS_GC (gc));
596   
597   real_draw_glyphs (drawable, gc, NULL, font,
598                     x, y, glyphs);
599 }
600
601 /**
602  * gdk_draw_glyphs_transformed:
603  * @drawable: a #GdkDrawable
604  * @gc: a #GdkGC
605  * @matrix: (allow-none): a #PangoMatrix, or %NULL to use an identity transformation
606  * @font: the font in which to draw the string
607  * @x:       the x position of the start of the string (in Pango
608  *           units in user space coordinates)
609  * @y:       the y position of the baseline (in Pango units
610  *           in user space coordinates)
611  * @glyphs:  the glyph string to draw
612  * 
613  * Renders a #PangoGlyphString onto a drawable, possibly
614  * transforming the layed-out coordinates through a transformation
615  * matrix. Note that the transformation matrix for @font is not
616  * changed, so to produce correct rendering results, the @font
617  * must have been loaded using a #PangoContext with an identical
618  * transformation matrix to that passed in to this function.
619  *
620  * See also gdk_draw_glyphs(), gdk_draw_layout().
621  *
622  * Since: 2.6
623  **/
624 void
625 gdk_draw_glyphs_transformed (GdkDrawable       *drawable,
626                              GdkGC             *gc,
627                              const PangoMatrix *matrix,
628                              PangoFont         *font,
629                              gint               x,
630                              gint               y,
631                              PangoGlyphString  *glyphs)
632 {
633   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
634   g_return_if_fail (GDK_IS_GC (gc));
635
636   real_draw_glyphs (drawable, gc, matrix, font,
637                     x / PANGO_SCALE, y / PANGO_SCALE, glyphs);
638 }
639
640 /**
641  * gdk_draw_trapezoids:
642  * @drawable: a #GdkDrawable
643  * @gc: a #GdkGC
644  * @trapezoids: an array of #GdkTrapezoid structures
645  * @n_trapezoids: the number of trapezoids to draw
646  * 
647  * Draws a set of anti-aliased trapezoids. The trapezoids are
648  * combined using saturation addition, then drawn over the background
649  * as a set. This is low level functionality used internally to implement
650  * rotated underlines and backgrouds when rendering a PangoLayout and is
651  * likely not useful for applications.
652  *
653  * Since: 2.6
654  **/
655 void
656 gdk_draw_trapezoids (GdkDrawable        *drawable,
657                      GdkGC              *gc,
658                      const GdkTrapezoid *trapezoids,
659                      gint                n_trapezoids)
660 {
661   cairo_t *cr;
662   int i;
663
664   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
665   g_return_if_fail (GDK_IS_GC (gc));
666   g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL);
667
668   cr = gdk_cairo_create (drawable);
669   _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable);
670   
671   for (i = 0; i < n_trapezoids; i++)
672     {
673       cairo_move_to (cr, trapezoids[i].x11, trapezoids[i].y1);
674       cairo_line_to (cr, trapezoids[i].x21, trapezoids[i].y1);
675       cairo_line_to (cr, trapezoids[i].x22, trapezoids[i].y2);
676       cairo_line_to (cr, trapezoids[i].x12, trapezoids[i].y2);
677       cairo_close_path (cr);
678     }
679
680   cairo_fill (cr);
681
682   cairo_destroy (cr);
683 }
684
685 static GdkDrawable *
686 gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
687                                           gint         x,
688                                           gint         y,
689                                           gint         width,
690                                           gint         height,
691                                           gint        *composite_x_offset,
692                                           gint        *composite_y_offset)
693 {
694   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
695
696   *composite_x_offset = 0;
697   *composite_y_offset = 0;
698   
699   return g_object_ref (drawable);
700 }
701
702 /**
703  * gdk_drawable_get_clip_region:
704  * @drawable: a #GdkDrawable
705  * 
706  * Computes the region of a drawable that potentially can be written
707  * to by drawing primitives. This region will not take into account
708  * the clip region for the GC, and may also not take into account
709  * other factors such as if the window is obscured by other windows,
710  * but no area outside of this region will be affected by drawing
711  * primitives.
712  * 
713  * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
714  *          when you are done.
715  **/
716 cairo_region_t *
717 gdk_drawable_get_clip_region (GdkDrawable *drawable)
718 {
719   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
720
721   return GDK_DRAWABLE_GET_CLASS (drawable)->get_clip_region (drawable);
722 }
723
724 /**
725  * gdk_drawable_get_visible_region:
726  * @drawable: a #GdkDrawable
727  * 
728  * Computes the region of a drawable that is potentially visible.
729  * This does not necessarily take into account if the window is
730  * obscured by other windows, but no area outside of this region
731  * is visible.
732  * 
733  * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
734  *          when you are done.
735  **/
736 cairo_region_t *
737 gdk_drawable_get_visible_region (GdkDrawable *drawable)
738 {
739   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
740
741   return GDK_DRAWABLE_GET_CLASS (drawable)->get_visible_region (drawable);
742 }
743
744 static cairo_region_t *
745 gdk_drawable_real_get_visible_region (GdkDrawable *drawable)
746 {
747   GdkRectangle rect;
748
749   rect.x = 0;
750   rect.y = 0;
751
752   gdk_drawable_get_size (drawable, &rect.width, &rect.height);
753
754   return cairo_region_create_rectangle (&rect);
755 }
756
757 /**
758  * _gdk_drawable_ref_cairo_surface:
759  * @drawable: a #GdkDrawable
760  * 
761  * Obtains a #cairo_surface_t for the given drawable. If a
762  * #cairo_surface_t for the drawable already exists, it will be
763  * referenced, otherwise a new surface will be created.
764  * 
765  * Return value: a newly referenced #cairo_surface_t that points
766  *  to @drawable. Unref with cairo_surface_destroy()
767  **/
768 cairo_surface_t *
769 _gdk_drawable_ref_cairo_surface (GdkDrawable *drawable)
770 {
771   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
772
773   return GDK_DRAWABLE_GET_CLASS (drawable)->ref_cairo_surface (drawable);
774 }
775
776 /* Implementation of the old vfunc in terms of the new one
777    in case someone calls it directly (which they shouldn't!) */
778 static void
779 gdk_drawable_real_draw_drawable (GdkDrawable  *drawable,
780                                  GdkGC         *gc,
781                                  GdkDrawable  *src,
782                                  gint           xsrc,
783                                  gint           ysrc,
784                                  gint           xdest,
785                                  gint           ydest,
786                                  gint           width,
787                                  gint           height)
788 {
789   GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable,
790                                                              gc,
791                                                              src,
792                                                              xsrc,
793                                                              ysrc,
794                                                              xdest,
795                                                              ydest,
796                                                              width,
797                                                              height,
798                                                              src);
799 }
800
801 /************************************************************************/
802
803 /**
804  * _gdk_drawable_get_scratch_gc:
805  * @drawable: A #GdkDrawable
806  * @graphics_exposures: Whether the returned #GdkGC should generate graphics exposures 
807  * 
808  * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has
809  * the standard values for @drawable, except for the graphics_exposures
810  * field which is determined by the @graphics_exposures parameter.
811  *
812  * The foreground color of the returned #GdkGC is undefined. The #GdkGC
813  * must not be altered in any way, except to change its foreground color.
814  * 
815  * Return value: A #GdkGC suitable for drawing on @drawable
816  * 
817  * Since: 2.4
818  **/
819 GdkGC *
820 _gdk_drawable_get_scratch_gc (GdkDrawable *drawable,
821                               gboolean     graphics_exposures)
822 {
823   GdkScreen *screen;
824   gint depth;
825
826   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
827
828   screen = gdk_drawable_get_screen (drawable);
829
830   g_return_val_if_fail (!screen->closed, NULL);
831
832   depth = gdk_drawable_get_depth (drawable) - 1;
833
834   if (graphics_exposures)
835     {
836       if (!screen->exposure_gcs[depth])
837         {
838           GdkGCValues values;
839           GdkGCValuesMask mask;
840
841           values.graphics_exposures = TRUE;
842           mask = GDK_GC_EXPOSURES;  
843
844           screen->exposure_gcs[depth] =
845             gdk_gc_new_with_values (drawable, &values, mask);
846         }
847
848       return screen->exposure_gcs[depth];
849     }
850   else
851     {
852       if (!screen->normal_gcs[depth])
853         {
854           screen->normal_gcs[depth] =
855             gdk_gc_new (drawable);
856         }
857
858       return screen->normal_gcs[depth];
859     }
860 }
861
862 /**
863  * _gdk_drawable_get_subwindow_scratch_gc:
864  * @drawable: A #GdkDrawable
865  * 
866  * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has
867  * the standard values for @drawable, except for the graphics_exposures
868  * field which is %TRUE and the subwindow mode which is %GDK_INCLUDE_INFERIORS.
869  *
870  * The foreground color of the returned #GdkGC is undefined. The #GdkGC
871  * must not be altered in any way, except to change its foreground color.
872  * 
873  * Return value: A #GdkGC suitable for drawing on @drawable
874  * 
875  * Since: 2.18
876  **/
877 GdkGC *
878 _gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable)
879 {
880   GdkScreen *screen;
881   gint depth;
882
883   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
884
885   screen = gdk_drawable_get_screen (drawable);
886
887   g_return_val_if_fail (!screen->closed, NULL);
888
889   depth = gdk_drawable_get_depth (drawable) - 1;
890
891   if (!screen->subwindow_gcs[depth])
892     {
893       GdkGCValues values;
894       GdkGCValuesMask mask;
895       
896       values.graphics_exposures = TRUE;
897       values.subwindow_mode = GDK_INCLUDE_INFERIORS;
898       mask = GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW;  
899       
900       screen->subwindow_gcs[depth] =
901         gdk_gc_new_with_values (drawable, &values, mask);
902     }
903   
904   return screen->subwindow_gcs[depth];
905 }
906
907
908 /*
909  * _gdk_drawable_get_source_drawable:
910  * @drawable: a #GdkDrawable
911  *
912  * Returns a drawable for the passed @drawable that is guaranteed to be
913  * usable to create a pixmap (e.g.: not an offscreen window).
914  *
915  * Since: 2.16
916  */
917 GdkDrawable *
918 _gdk_drawable_get_source_drawable (GdkDrawable *drawable)
919 {
920   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
921
922   if (GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable)
923     return GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable (drawable);
924
925   return drawable;
926 }
927
928 cairo_surface_t *
929 _gdk_drawable_create_cairo_surface (GdkDrawable *drawable,
930                                     int width,
931                                     int height)
932 {
933   return GDK_DRAWABLE_GET_CLASS (drawable)->create_cairo_surface (drawable,
934                                                                   width, height);
935 }