]> Pileus Git - ~andy/gtk/blob - gdk/gdkgc.c
0e03ae29131ee4d3476b274b5fd0411996449e94
[~andy/gtk] / gdk / gdkgc.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 <string.h>
29
30 #include "gdkcairo.h"
31 #include "gdkgc.h"
32 #include "gdkinternals.h"
33 #include "gdkpixmap.h"
34 #include "gdkrgb.h"
35 #include "gdkprivate.h"
36 #include "gdkalias.h"
37
38 static void gdk_gc_finalize   (GObject      *object);
39
40 typedef struct _GdkGCPrivate GdkGCPrivate;
41
42 struct _GdkGCPrivate
43 {
44   GdkRegion *clip_region;
45
46   GdkFill fill;
47   GdkBitmap *stipple;
48   GdkPixmap *tile;
49   
50   guint32 fg_pixel;
51   guint32 bg_pixel;
52 };
53
54 #define GDK_GC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_GC, GdkGCPrivate))
55
56 G_DEFINE_TYPE (GdkGC, gdk_gc, G_TYPE_OBJECT)
57
58 static void
59 gdk_gc_class_init (GdkGCClass *class)
60 {
61   GObjectClass *object_class = G_OBJECT_CLASS (class);
62   
63   object_class->finalize = gdk_gc_finalize;
64
65   g_type_class_add_private (object_class, sizeof (GdkGCPrivate));
66 }
67
68 static void
69 gdk_gc_init (GdkGC *gc)
70 {
71   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
72
73   priv->fill = GDK_SOLID;
74
75   /* These are the default X11 value, which we match. They are clearly
76    * wrong for TrueColor displays, so apps have to change them.
77    */
78   priv->fg_pixel = 0;
79   priv->bg_pixel = 1;
80 }
81
82 /**
83  * gdk_gc_new:
84  * @drawable: a #GdkDrawable. The created GC must always be used
85  *   with drawables of the same depth as this one.
86  *
87  * Create a new graphics context with default values. 
88  *
89  * Returns: the new graphics context.
90  **/
91 GdkGC*
92 gdk_gc_new (GdkDrawable *drawable)
93 {
94   g_return_val_if_fail (drawable != NULL, NULL);
95
96   return gdk_gc_new_with_values (drawable, NULL, 0);
97 }
98
99 /**
100  * gdk_gc_new_with_values:
101  * @drawable: a #GdkDrawable. The created GC must always be used
102  *   with drawables of the same depth as this one.
103  * @values: a structure containing initial values for the GC.
104  * @values_mask: a bit mask indicating which fields in @values
105  *   are set.
106  * 
107  * Create a new GC with the given initial values.
108  * 
109  * Return value: the new graphics context.
110  **/
111 GdkGC*
112 gdk_gc_new_with_values (GdkDrawable     *drawable,
113                         GdkGCValues     *values,
114                         GdkGCValuesMask  values_mask)
115 {
116   g_return_val_if_fail (drawable != NULL, NULL);
117
118   return GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable,
119                                                        values,
120                                                        values_mask);
121 }
122
123 /**
124  * _gdk_gc_init:
125  * @gc: a #GdkGC
126  * @drawable: a #GdkDrawable.
127  * @values: a structure containing initial values for the GC.
128  * @values_mask: a bit mask indicating which fields in @values
129  *   are set.
130  * 
131  * Does initialization of the generic portions of a #GdkGC
132  * created with the specified values and values_mask. This
133  * should be called out of the implementation of
134  * GdkDrawable.create_gc() immediately after creating the
135  * #GdkGC object.
136  **/
137 void
138 _gdk_gc_init (GdkGC           *gc,
139               GdkDrawable     *drawable,
140               GdkGCValues     *values,
141               GdkGCValuesMask  values_mask)
142 {
143   GdkGCPrivate *priv;
144
145   g_return_if_fail (GDK_IS_GC (gc));
146
147   priv = GDK_GC_GET_PRIVATE (gc);
148
149   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
150     gc->clip_x_origin = values->clip_x_origin;
151   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
152     gc->clip_y_origin = values->clip_y_origin;
153   if (values_mask & GDK_GC_TS_X_ORIGIN)
154     gc->ts_x_origin = values->ts_x_origin;
155   if (values_mask & GDK_GC_TS_Y_ORIGIN)
156     gc->ts_y_origin = values->ts_y_origin;
157   if (values_mask & GDK_GC_FILL)
158     priv->fill = values->fill;
159   if (values_mask & GDK_GC_STIPPLE)
160     {
161       priv->stipple = values->stipple;
162       if (priv->stipple)
163         g_object_ref (priv->stipple);
164     }
165   if (values_mask & GDK_GC_TILE)
166     {
167       priv->tile = values->tile;
168       if (priv->tile)
169         g_object_ref (priv->tile);
170     }
171   if (values_mask & GDK_GC_FOREGROUND)
172     priv->fg_pixel = values->foreground.pixel;
173   if (values_mask & GDK_GC_BACKGROUND)
174     priv->bg_pixel = values->background.pixel;
175
176   gc->colormap = gdk_drawable_get_colormap (drawable);
177   if (gc->colormap)
178     g_object_ref (gc->colormap);
179 }
180
181 static void
182 gdk_gc_finalize (GObject *object)
183 {
184   GdkGC *gc = GDK_GC (object);
185   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
186   
187   if (priv->clip_region)
188     gdk_region_destroy (priv->clip_region);
189   if (gc->colormap)
190     g_object_unref (gc->colormap);
191   if (priv->tile)
192     g_object_unref (priv->tile);
193   if (priv->stipple)
194     g_object_unref (priv->stipple);
195
196   G_OBJECT_CLASS (gdk_gc_parent_class)->finalize (object);
197 }
198
199 /**
200  * gdk_gc_ref:
201  * @gc: a #GdkGC
202  *
203  * Deprecated function; use g_object_ref() instead.
204  *
205  * Return value: the gc.
206  **/
207 GdkGC *
208 gdk_gc_ref (GdkGC *gc)
209 {
210   return (GdkGC *) g_object_ref (gc);
211 }
212
213 /**
214  * gdk_gc_unref:
215  * @gc: a #GdkGC
216  *
217  * Decrement the reference count of @gc.
218  *
219  * Deprecated: Use g_object_unref() instead.
220  **/
221 void
222 gdk_gc_unref (GdkGC *gc)
223 {
224   g_object_unref (gc);
225 }
226
227 /**
228  * gdk_gc_get_values:
229  * @gc:  a #GdkGC.
230  * @values: the #GdkGCValues structure in which to store the results.
231  * 
232  * Retrieves the current values from a graphics context. Note that 
233  * only the pixel values of the @values->foreground and @values->background
234  * are filled, use gdk_colormap_query_color() to obtain the rgb values
235  * if you need them.
236  **/
237 void
238 gdk_gc_get_values (GdkGC       *gc,
239                    GdkGCValues *values)
240 {
241   g_return_if_fail (GDK_IS_GC (gc));
242   g_return_if_fail (values != NULL);
243
244   GDK_GC_GET_CLASS (gc)->get_values (gc, values);
245 }
246
247 /**
248  * gdk_gc_set_values:
249  * @gc: a #GdkGC
250  * @values: struct containing the new values
251  * @values_mask: mask indicating which struct fields are to be used
252  *
253  * Sets attributes of a graphics context in bulk. For each flag set in
254  * @values_mask, the corresponding field will be read from @values and
255  * set as the new value for @gc. If you're only setting a few values
256  * on @gc, calling individual "setter" functions is likely more
257  * convenient.
258  * 
259  **/
260 void
261 gdk_gc_set_values (GdkGC           *gc,
262                    GdkGCValues     *values,
263                    GdkGCValuesMask  values_mask)
264 {
265   GdkGCPrivate *priv;
266
267   g_return_if_fail (GDK_IS_GC (gc));
268   g_return_if_fail (values != NULL);
269
270   priv = GDK_GC_GET_PRIVATE (gc);
271
272   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
273     gc->clip_x_origin = values->clip_x_origin;
274   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
275     gc->clip_y_origin = values->clip_y_origin;
276   if (values_mask & GDK_GC_TS_X_ORIGIN)
277     gc->ts_x_origin = values->ts_x_origin;
278   if (values_mask & GDK_GC_TS_Y_ORIGIN)
279     gc->ts_y_origin = values->ts_y_origin;
280   if (values_mask & GDK_GC_CLIP_MASK)
281     {
282       GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
283       if (priv->clip_region)
284         {
285           gdk_region_destroy (priv->clip_region);
286           priv->clip_region = NULL;
287         }
288     }
289   if (values_mask & GDK_GC_FILL)
290     priv->fill = values->fill;
291   if (values_mask & GDK_GC_STIPPLE)
292     {
293       if (priv->stipple != values->stipple)
294         {
295           if (priv->stipple)
296             g_object_unref (priv->stipple);
297           priv->stipple = values->stipple;
298           if (priv->stipple)
299             g_object_ref (priv->stipple);
300         }
301     }
302   if (values_mask & GDK_GC_TILE)
303     {
304       if (priv->tile != values->tile)
305         {
306           if (priv->tile)
307             g_object_unref (priv->tile);
308           priv->tile = values->tile;
309           if (priv->tile)
310             g_object_ref (priv->tile);
311         }
312     }
313   if (values_mask & GDK_GC_FOREGROUND)
314     priv->fg_pixel = values->foreground.pixel;
315   if (values_mask & GDK_GC_BACKGROUND)
316     priv->bg_pixel = values->background.pixel;
317   
318   GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask);
319 }
320
321 /**
322  * gdk_gc_set_foreground:
323  * @gc: a #GdkGC.
324  * @color: the new foreground color.
325  * 
326  * Sets the foreground color for a graphics context.
327  * Note that this function uses @color->pixel, use 
328  * gdk_gc_set_rgb_fg_color() to specify the foreground 
329  * color as red, green, blue components.
330  **/
331 void
332 gdk_gc_set_foreground (GdkGC          *gc,
333                        const GdkColor *color)
334 {
335   GdkGCValues values;
336
337   g_return_if_fail (GDK_IS_GC (gc));
338   g_return_if_fail (color != NULL);
339
340   values.foreground = *color;
341   gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND);
342 }
343
344 /**
345  * gdk_gc_set_background:
346  * @gc: a #GdkGC.
347  * @color: the new background color.
348  * 
349  * Sets the background color for a graphics context.
350  * Note that this function uses @color->pixel, use 
351  * gdk_gc_set_rgb_bg_color() to specify the background 
352  * color as red, green, blue components.
353  **/
354 void
355 gdk_gc_set_background (GdkGC          *gc,
356                        const GdkColor *color)
357 {
358   GdkGCValues values;
359
360   g_return_if_fail (GDK_IS_GC (gc));
361   g_return_if_fail (color != NULL);
362
363   values.background = *color;
364   gdk_gc_set_values (gc, &values, GDK_GC_BACKGROUND);
365 }
366
367 /**
368  * gdk_gc_set_font:
369  * @gc: a #GdkGC.
370  * @font: the new font. 
371  * 
372  * Sets the font for a graphics context. (Note that
373  * all text-drawing functions in GDK take a @font
374  * argument; the value set here is used when that
375  * argument is %NULL.)
376  **/
377 void
378 gdk_gc_set_font (GdkGC   *gc,
379                  GdkFont *font)
380 {
381   GdkGCValues values;
382
383   g_return_if_fail (GDK_IS_GC (gc));
384   g_return_if_fail (font != NULL);
385
386   values.font = font;
387   gdk_gc_set_values (gc, &values, GDK_GC_FONT);
388 }
389
390 /**
391  * gdk_gc_set_function:
392  * @gc: a #GdkGC.
393  * @function: the #GdkFunction to use
394  * 
395  * Determines how the current pixel values and the
396  * pixel values being drawn are combined to produce
397  * the final pixel values.
398  **/
399 void
400 gdk_gc_set_function (GdkGC       *gc,
401                      GdkFunction  function)
402 {
403   GdkGCValues values;
404
405   g_return_if_fail (GDK_IS_GC (gc));
406
407   values.function = function;
408   gdk_gc_set_values (gc, &values, GDK_GC_FUNCTION);
409 }
410
411 /**
412  * gdk_gc_set_fill:
413  * @gc: a #GdkGC.
414  * @fill: the new fill mode.
415  * 
416  * Set the fill mode for a graphics context.
417  **/
418 void
419 gdk_gc_set_fill (GdkGC   *gc,
420                  GdkFill  fill)
421 {
422   GdkGCValues values;
423
424   g_return_if_fail (GDK_IS_GC (gc));
425
426   values.fill = fill;
427   gdk_gc_set_values (gc, &values, GDK_GC_FILL);
428 }
429
430 /**
431  * gdk_gc_set_tile:
432  * @gc:  a #GdkGC.
433  * @tile:  the new tile pixmap.
434  * 
435  * Set a tile pixmap for a graphics context.
436  * This will only be used if the fill mode
437  * is %GDK_TILED.
438  **/
439 void
440 gdk_gc_set_tile (GdkGC     *gc,
441                  GdkPixmap *tile)
442 {
443   GdkGCValues values;
444
445   g_return_if_fail (GDK_IS_GC (gc));
446
447   values.tile = tile;
448   gdk_gc_set_values (gc, &values, GDK_GC_TILE);
449 }
450
451 /**
452  * gdk_gc_set_stipple:
453  * @gc: a #GdkGC.
454  * @stipple: the new stipple bitmap.
455  * 
456  * Set the stipple bitmap for a graphics context. The
457  * stipple will only be used if the fill mode is
458  * %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED.
459  **/
460 void
461 gdk_gc_set_stipple (GdkGC     *gc,
462                     GdkPixmap *stipple)
463 {
464   GdkGCValues values;
465
466   g_return_if_fail (GDK_IS_GC (gc));
467
468   values.stipple = stipple;
469   gdk_gc_set_values (gc, &values, GDK_GC_STIPPLE);
470 }
471
472 /**
473  * gdk_gc_set_ts_origin:
474  * @gc:  a #GdkGC.
475  * @x: the x-coordinate of the origin.
476  * @y: the y-coordinate of the origin.
477  * 
478  * Set the origin when using tiles or stipples with
479  * the GC. The tile or stipple will be aligned such
480  * that the upper left corner of the tile or stipple
481  * will coincide with this point.
482  **/
483 void
484 gdk_gc_set_ts_origin (GdkGC *gc,
485                       gint   x,
486                       gint   y)
487 {
488   GdkGCValues values;
489
490   g_return_if_fail (GDK_IS_GC (gc));
491
492   values.ts_x_origin = x;
493   values.ts_y_origin = y;
494   
495   gdk_gc_set_values (gc, &values,
496                      GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
497 }
498
499 /**
500  * gdk_gc_set_clip_origin:
501  * @gc: a #GdkGC.
502  * @x: the x-coordinate of the origin.
503  * @y: the y-coordinate of the origin.
504  * 
505  * Sets the origin of the clip mask. The coordinates are
506  * interpreted relative to the upper-left corner of
507  * the destination drawable of the current operation.
508  **/
509 void
510 gdk_gc_set_clip_origin (GdkGC *gc,
511                         gint   x,
512                         gint   y)
513 {
514   GdkGCValues values;
515
516   g_return_if_fail (GDK_IS_GC (gc));
517
518   values.clip_x_origin = x;
519   values.clip_y_origin = y;
520   
521   gdk_gc_set_values (gc, &values,
522                      GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
523 }
524
525 /**
526  * gdk_gc_set_clip_mask:
527  * @gc: the #GdkGC.
528  * @mask: a bitmap.
529  * 
530  * Sets the clip mask for a graphics context from a bitmap.
531  * The clip mask is interpreted relative to the clip
532  * origin. (See gdk_gc_set_clip_origin()).
533  **/
534 void
535 gdk_gc_set_clip_mask (GdkGC     *gc,
536                       GdkBitmap *mask)
537 {
538   GdkGCValues values;
539   
540   g_return_if_fail (GDK_IS_GC (gc));
541   
542   values.clip_mask = mask;
543   gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK);
544 }
545
546 static void
547 _gdk_gc_set_clip_region_internal (GdkGC     *gc,
548                                   GdkRegion *region)
549 {
550   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
551
552   if (priv->clip_region)
553     gdk_region_destroy (priv->clip_region);
554
555   priv->clip_region = region;
556
557   _gdk_windowing_gc_set_clip_region (gc, region);
558 }
559
560 /**
561  * gdk_gc_set_clip_rectangle:
562  * @gc: a #GdkGC.
563  * @rectangle: the rectangle to clip to.
564  * 
565  * Sets the clip mask for a graphics context from a
566  * rectangle. The clip mask is interpreted relative to the clip
567  * origin. (See gdk_gc_set_clip_origin()).
568  **/
569 void
570 gdk_gc_set_clip_rectangle (GdkGC        *gc,
571                            GdkRectangle *rectangle)
572 {
573   GdkRegion *region;
574   
575   g_return_if_fail (GDK_IS_GC (gc));
576
577   if (rectangle)
578     region = gdk_region_rectangle (rectangle);
579   else
580     region = NULL;
581
582   _gdk_gc_set_clip_region_internal (gc, region);
583 }
584
585 /**
586  * gdk_gc_set_clip_region:
587  * @gc: a #GdkGC.
588  * @region: the #GdkRegion. 
589  * 
590  * Sets the clip mask for a graphics context from a region structure.
591  * The clip mask is interpreted relative to the clip origin. (See
592  * gdk_gc_set_clip_origin()).
593  **/
594 void
595 gdk_gc_set_clip_region (GdkGC     *gc,
596                         GdkRegion *region)
597 {
598   g_return_if_fail (GDK_IS_GC (gc));
599
600   if (region)
601     region = gdk_region_copy (region);
602   
603   _gdk_gc_set_clip_region_internal (gc, region);
604 }
605
606 /**
607  * _gdk_gc_get_clip_region:
608  * @gc: a #GdkGC
609  * 
610  * Gets the current clip region for @gc, if any.
611  * 
612  * Return value: the clip region for the GC, or %NULL.
613  *   (if a clip mask is set, the return will be %NULL)
614  *   This value is owned by the GC and must not be freed.
615  **/
616 GdkRegion *
617 _gdk_gc_get_clip_region (GdkGC *gc)
618 {
619   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
620
621   return GDK_GC_GET_PRIVATE (gc)->clip_region;
622 }
623
624 /**
625  * _gdk_gc_get_fill:
626  * @gc: a #GdkGC
627  * 
628  * Gets the current file style for the GC
629  * 
630  * Return value: the file style for the GC
631  **/
632 GdkFill
633 _gdk_gc_get_fill (GdkGC *gc)
634 {
635   g_return_val_if_fail (GDK_IS_GC (gc), GDK_SOLID);
636
637   return GDK_GC_GET_PRIVATE (gc)->fill;
638 }
639
640 /**
641  * _gdk_gc_get_tile:
642  * @gc: a #GdkGC
643  * 
644  * Gets the tile pixmap for @gc, if any
645  * 
646  * Return value: the tile set on the GC, or %NULL. The
647  *   value is owned by the GC and must not be freed.
648  **/
649 GdkPixmap *
650 _gdk_gc_get_tile (GdkGC *gc)
651 {
652   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
653
654   return GDK_GC_GET_PRIVATE (gc)->tile;
655 }
656
657 /**
658  * _gdk_gc_get_stipple:
659  * @gc: a #GdkGC
660  * 
661  * Gets the stipple pixmap for @gc, if any
662  * 
663  * Return value: the stipple set on the GC, or %NULL. The
664  *   value is owned by the GC and must not be freed.
665  **/
666 GdkBitmap *
667 _gdk_gc_get_stipple (GdkGC *gc)
668 {
669   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
670
671   return GDK_GC_GET_PRIVATE (gc)->stipple;
672 }
673
674 /**
675  * _gdk_gc_get_fg_pixel:
676  * @gc: a #GdkGC
677  * 
678  * Gets the foreground pixel value for @gc. If the
679  * foreground pixel has never been set, returns the
680  * default value 0.
681  * 
682  * Return value: the foreground pixel value of the GC
683  **/
684 guint32
685 _gdk_gc_get_fg_pixel (GdkGC *gc)
686 {
687   g_return_val_if_fail (GDK_IS_GC (gc), 0);
688   
689   return GDK_GC_GET_PRIVATE (gc)->fg_pixel;
690 }
691
692 /**
693  * _gdk_gc_get_bg_pixel:
694  * @gc: a #GdkGC
695  * 
696  * Gets the background pixel value for @gc.If the
697  * foreground pixel has never been set, returns the
698  * default value 1.
699  * 
700  * Return value: the foreground pixel value of the GC
701  **/
702 guint32
703 _gdk_gc_get_bg_pixel (GdkGC *gc)
704 {
705   g_return_val_if_fail (GDK_IS_GC (gc), 0);
706   
707   return GDK_GC_GET_PRIVATE (gc)->bg_pixel;
708 }
709
710 /**
711  * gdk_gc_set_subwindow:
712  * @gc: a #GdkGC.
713  * @mode: the subwindow mode.
714  * 
715  * Sets how drawing with this GC on a window will affect child
716  * windows of that window. 
717  **/
718 void
719 gdk_gc_set_subwindow (GdkGC            *gc,
720                       GdkSubwindowMode  mode)
721 {
722   GdkGCValues values;
723
724   g_return_if_fail (GDK_IS_GC (gc));
725
726   values.subwindow_mode = mode;
727   gdk_gc_set_values (gc, &values, GDK_GC_SUBWINDOW);
728 }
729
730 /**
731  * gdk_gc_set_exposures:
732  * @gc: a #GdkGC.
733  * @exposures: if %TRUE, exposure events will be generated.
734  * 
735  * Sets whether copying non-visible portions of a drawable
736  * using this graphics context generate exposure events
737  * for the corresponding regions of the destination
738  * drawable. (See gdk_draw_drawable()).
739  **/
740 void
741 gdk_gc_set_exposures (GdkGC     *gc,
742                       gboolean   exposures)
743 {
744   GdkGCValues values;
745
746   g_return_if_fail (GDK_IS_GC (gc));
747
748   values.graphics_exposures = exposures;
749   gdk_gc_set_values (gc, &values, GDK_GC_EXPOSURES);
750 }
751
752 /**
753  * gdk_gc_set_line_attributes:
754  * @gc: a #GdkGC.
755  * @line_width: the width of lines.
756  * @line_style: the dash-style for lines.
757  * @cap_style: the manner in which the ends of lines are drawn.
758  * @join_style: the in which lines are joined together.
759  * 
760  * Sets various attributes of how lines are drawn. See
761  * the corresponding members of #GdkGCValues for full
762  * explanations of the arguments.
763  **/
764 void
765 gdk_gc_set_line_attributes (GdkGC       *gc,
766                             gint         line_width,
767                             GdkLineStyle line_style,
768                             GdkCapStyle  cap_style,
769                             GdkJoinStyle join_style)
770 {
771   GdkGCValues values;
772
773   values.line_width = line_width;
774   values.line_style = line_style;
775   values.cap_style = cap_style;
776   values.join_style = join_style;
777
778   gdk_gc_set_values (gc, &values,
779                      GDK_GC_LINE_WIDTH |
780                      GDK_GC_LINE_STYLE |
781                      GDK_GC_CAP_STYLE |
782                      GDK_GC_JOIN_STYLE);
783 }
784
785 /**
786  * gdk_gc_set_dashes:
787  * @gc: a #GdkGC.
788  * @dash_offset: the phase of the dash pattern.
789  * @dash_list: an array of dash lengths.
790  * @n: the number of elements in @dash_list.
791  * 
792  * Sets the way dashed-lines are drawn. Lines will be
793  * drawn with alternating on and off segments of the
794  * lengths specified in @dash_list. The manner in
795  * which the on and off segments are drawn is determined
796  * by the @line_style value of the GC. (This can
797  * be changed with gdk_gc_set_line_attributes().)
798  *
799  * The @dash_offset defines the phase of the pattern, 
800  * specifying how many pixels into the dash-list the pattern 
801  * should actually begin.
802  **/
803 void
804 gdk_gc_set_dashes (GdkGC *gc,
805                    gint   dash_offset,
806                    gint8  dash_list[],
807                    gint   n)
808 {
809   g_return_if_fail (GDK_IS_GC (gc));
810   g_return_if_fail (dash_list != NULL);
811
812   GDK_GC_GET_CLASS (gc)->set_dashes (gc, dash_offset, dash_list, n);
813 }
814
815 /**
816  * gdk_gc_offset:
817  * @gc: a #GdkGC
818  * @x_offset: amount by which to offset the GC in the X direction
819  * @y_offset: amount by which to offset the GC in the Y direction
820  * 
821  * Offset attributes such as the clip and tile-stipple origins
822  * of the GC so that drawing at x - x_offset, y - y_offset with
823  * the offset GC  has the same effect as drawing at x, y with the original
824  * GC.
825  **/
826 void
827 gdk_gc_offset (GdkGC *gc,
828                gint   x_offset,
829                gint   y_offset)
830 {
831   if (x_offset != 0 || y_offset != 0)
832     {
833       GdkGCValues values;
834
835       values.clip_x_origin = gc->clip_x_origin - x_offset;
836       values.clip_y_origin = gc->clip_y_origin - y_offset;
837       values.ts_x_origin = gc->ts_x_origin - x_offset;
838       values.ts_y_origin = gc->ts_y_origin - y_offset;
839       
840       gdk_gc_set_values (gc, &values,
841                          GDK_GC_CLIP_X_ORIGIN |
842                          GDK_GC_CLIP_Y_ORIGIN |
843                          GDK_GC_TS_X_ORIGIN |
844                          GDK_GC_TS_Y_ORIGIN);
845     }
846 }
847
848 /**
849  * gdk_gc_copy:
850  * @dst_gc: the destination graphics context.
851  * @src_gc: the source graphics context.
852  * 
853  * Copy the set of values from one graphics context
854  * onto another graphics context.
855  **/
856 void
857 gdk_gc_copy (GdkGC *dst_gc,
858              GdkGC *src_gc)
859 {
860   GdkGCPrivate *dst_priv, *src_priv;
861   
862   g_return_if_fail (GDK_IS_GC (dst_gc));
863   g_return_if_fail (GDK_IS_GC (src_gc));
864
865   dst_priv = GDK_GC_GET_PRIVATE (dst_gc);
866   src_priv = GDK_GC_GET_PRIVATE (src_gc);
867
868   _gdk_windowing_gc_copy (dst_gc, src_gc);
869
870   dst_gc->clip_x_origin = src_gc->clip_x_origin;
871   dst_gc->clip_y_origin = src_gc->clip_y_origin;
872   dst_gc->ts_x_origin = src_gc->ts_x_origin;
873   dst_gc->ts_y_origin = src_gc->ts_y_origin;
874
875   if (src_gc->colormap)
876     g_object_ref (src_gc->colormap);
877
878   if (dst_gc->colormap)
879     g_object_unref (dst_gc->colormap);
880
881   dst_gc->colormap = src_gc->colormap;
882
883   if (dst_priv->clip_region)
884     gdk_region_destroy (dst_priv->clip_region);
885
886   if (src_priv->clip_region)
887     dst_priv->clip_region = gdk_region_copy (src_priv->clip_region);
888   else
889     dst_priv->clip_region = NULL;
890   
891   dst_priv->fill = src_priv->fill;
892   
893   if (dst_priv->stipple)
894     g_object_unref (dst_priv->stipple);
895   dst_priv->stipple = src_priv->stipple;
896   if (dst_priv->stipple)
897     g_object_ref (dst_priv->stipple);
898   
899   if (dst_priv->tile)
900     g_object_unref (dst_priv->tile);
901   dst_priv->tile = src_priv->tile;
902   if (dst_priv->tile)
903     g_object_ref (dst_priv->tile);
904
905   dst_priv->fg_pixel = src_priv->fg_pixel;
906   dst_priv->bg_pixel = src_priv->bg_pixel;
907 }
908
909 /**
910  * gdk_gc_set_colormap:
911  * @gc: a #GdkGC
912  * @colormap: a #GdkColormap
913  * 
914  * Sets the colormap for the GC to the given colormap. The depth
915  * of the colormap's visual must match the depth of the drawable
916  * for which the GC was created.
917  **/
918 void
919 gdk_gc_set_colormap (GdkGC       *gc,
920                      GdkColormap *colormap)
921 {
922   g_return_if_fail (GDK_IS_GC (gc));
923   g_return_if_fail (GDK_IS_COLORMAP (colormap));
924
925   if (gc->colormap != colormap)
926     {
927       if (gc->colormap)
928         g_object_unref (gc->colormap);
929
930       gc->colormap = colormap;
931       g_object_ref (gc->colormap);
932     }
933     
934 }
935
936 /**
937  * gdk_gc_get_colormap:
938  * @gc: a #GdkGC
939  * 
940  * Retrieves the colormap for a given GC, if it exists.
941  * A GC will have a colormap if the drawable for which it was created
942  * has a colormap, or if a colormap was set explicitely with
943  * gdk_gc_set_colormap.
944  * 
945  * Return value: the colormap of @gc, or %NULL if @gc doesn't have one.
946  **/
947 GdkColormap *
948 gdk_gc_get_colormap (GdkGC *gc)
949 {
950   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
951
952   return gc->colormap;
953 }
954
955 static GdkColormap *
956 gdk_gc_get_colormap_warn (GdkGC *gc)
957 {
958   GdkColormap *colormap = gdk_gc_get_colormap (gc);
959   if (!colormap)
960     {
961       g_warning ("gdk_gc_set_rgb_fg_color() and gdk_gc_set_rgb_bg_color() can\n"
962                  "only be used on GC's with a colormap. A GC will have a colormap\n"
963                  "if it is created for a drawable with a colormap, or if a\n"
964                  "colormap has been set explicitly with gdk_gc_set_colormap.\n");
965       return NULL;
966     }
967
968   return colormap;
969 }
970
971 /**
972  * gdk_gc_set_rgb_fg_color:
973  * @gc: a #GdkGC
974  * @color: an unallocated #GdkColor.
975  * 
976  * Set the foreground color of a GC using an unallocated color. The
977  * pixel value for the color will be determined using GdkRGB. If the
978  * colormap for the GC has not previously been initialized for GdkRGB,
979  * then for pseudo-color colormaps (colormaps with a small modifiable
980  * number of colors), a colorcube will be allocated in the colormap.
981  * 
982  * Calling this function for a GC without a colormap is an error.
983  **/
984 void
985 gdk_gc_set_rgb_fg_color (GdkGC          *gc,
986                          const GdkColor *color)
987 {
988   GdkColormap *cmap;
989   GdkColor tmp_color;
990
991   g_return_if_fail (GDK_IS_GC (gc));
992   g_return_if_fail (color != NULL);
993
994   cmap = gdk_gc_get_colormap_warn (gc);
995   if (!cmap)
996     return;
997
998   tmp_color = *color;
999   gdk_rgb_find_color (cmap, &tmp_color);
1000   gdk_gc_set_foreground (gc, &tmp_color);
1001 }
1002
1003 /**
1004  * gdk_gc_set_rgb_bg_color:
1005  * @gc: a #GdkGC
1006  * @color: an unallocated #GdkColor.
1007  * 
1008  * Set the background color of a GC using an unallocated color. The
1009  * pixel value for the color will be determined using GdkRGB. If the
1010  * colormap for the GC has not previously been initialized for GdkRGB,
1011  * then for pseudo-color colormaps (colormaps with a small modifiable
1012  * number of colors), a colorcube will be allocated in the colormap.
1013  * 
1014  * Calling this function for a GC without a colormap is an error.
1015  **/
1016 void
1017 gdk_gc_set_rgb_bg_color (GdkGC          *gc,
1018                          const GdkColor *color)
1019 {
1020   GdkColormap *cmap;
1021   GdkColor tmp_color;
1022
1023   g_return_if_fail (GDK_IS_GC (gc));
1024   g_return_if_fail (color != NULL);
1025
1026   cmap = gdk_gc_get_colormap_warn (gc);
1027   if (!cmap)
1028     return;
1029
1030   tmp_color = *color;
1031   gdk_rgb_find_color (cmap, &tmp_color);
1032   gdk_gc_set_background (gc, &tmp_color);
1033 }
1034
1035 static cairo_surface_t *
1036 make_stipple_tile_surface (cairo_t   *cr,
1037                            GdkBitmap *stipple,
1038                            GdkColor  *foreground,
1039                            GdkColor  *background)
1040 {
1041   cairo_t *tmp_cr;
1042   cairo_surface_t *surface; 
1043   cairo_surface_t *alpha_surface;
1044   gint width, height;
1045
1046   gdk_drawable_get_size (stipple,
1047                          &width, &height);
1048   
1049   alpha_surface = _gdk_drawable_ref_cairo_surface (stipple);
1050   
1051   surface = cairo_surface_create_similar (cairo_get_target (cr),
1052                                           CAIRO_CONTENT_COLOR_ALPHA,
1053                                           width, height);
1054
1055   tmp_cr = cairo_create (surface);
1056   
1057   cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SOURCE);
1058  
1059   if (background)
1060       gdk_cairo_set_source_color (tmp_cr, background);
1061   else
1062       cairo_set_source_rgba (tmp_cr, 0, 0, 0 ,0);
1063
1064   cairo_paint (tmp_cr);
1065
1066   cairo_set_operator (tmp_cr, CAIRO_OPERATOR_OVER);
1067
1068   gdk_cairo_set_source_color (tmp_cr, foreground);
1069   cairo_mask_surface (tmp_cr, alpha_surface, 0, 0);
1070   
1071   cairo_destroy (tmp_cr);
1072   cairo_surface_destroy (alpha_surface);
1073
1074   return surface;
1075 }
1076
1077 static void
1078 gc_get_foreground (GdkGC    *gc,
1079                    GdkColor *color)
1080 {
1081   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
1082   
1083   color->pixel = priv->bg_pixel;
1084
1085   if (gc->colormap)
1086     gdk_colormap_query_color (gc->colormap, priv->fg_pixel, color);
1087   else
1088     g_warning ("No colormap in gc_get_foreground");
1089 }
1090
1091 static void
1092 gc_get_background (GdkGC    *gc,
1093                    GdkColor *color)
1094 {
1095   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
1096   
1097   color->pixel = priv->bg_pixel;
1098
1099   if (gc->colormap)
1100     gdk_colormap_query_color (gc->colormap, priv->bg_pixel, color);
1101   else
1102     g_warning ("No colormap in gc_get_background");
1103 }
1104
1105 /**
1106  * _gdk_gc_update_context:
1107  * @gc: a #GdkGC
1108  * @cr: a #cairo_t
1109  * @override_foreground: a foreground color to use to override the
1110  *   foreground color of the GC
1111  * @override_stipple: a stipple pattern to use to override the
1112  *   stipple from the GC. If this is present and the fill mode
1113  *   of the GC isn't %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED
1114  *   the fill mode will be forced to %GDK_STIPPLED
1115  * @gc_changed: pass %FALSE if the @gc has not changed since the
1116  *     last call to this function
1117  * 
1118  * Set the attributes of a cairo context to match those of a #GdkGC
1119  * as far as possible. Some aspects of a #GdkGC, such as clip masks
1120  * and functions other than %GDK_COPY are not currently handled.
1121  **/
1122 void
1123 _gdk_gc_update_context (GdkGC     *gc,
1124                         cairo_t   *cr,
1125                         GdkColor  *override_foreground,
1126                         GdkBitmap *override_stipple,
1127                         gboolean   gc_changed)
1128 {
1129   GdkGCPrivate *priv;
1130   GdkFill fill;
1131   GdkColor foreground;
1132   GdkColor background;
1133   cairo_surface_t *tile_surface = NULL;
1134   GdkBitmap *stipple = NULL;
1135
1136   g_return_if_fail (GDK_IS_GC (gc));
1137   g_return_if_fail (cr != NULL);
1138   g_return_if_fail (override_stipple == NULL || GDK_IS_PIXMAP (override_stipple));
1139
1140   priv = GDK_GC_GET_PRIVATE (gc);
1141
1142   fill = priv->fill;
1143   if (override_stipple && fill != GDK_OPAQUE_STIPPLED)
1144     fill = GDK_STIPPLED;
1145
1146   if (fill != GDK_TILED)
1147     {
1148       if (override_foreground)
1149         foreground = *override_foreground;
1150       else
1151         gc_get_foreground (gc, &foreground);
1152     }
1153
1154   if (fill == GDK_OPAQUE_STIPPLED)
1155     gc_get_background (gc, &background);
1156
1157
1158   switch (fill)
1159     {
1160     case GDK_SOLID:
1161       break;
1162     case GDK_TILED:
1163       if (!priv->tile)
1164         fill = GDK_SOLID;
1165       break;
1166     case GDK_STIPPLED:
1167     case GDK_OPAQUE_STIPPLED:
1168       if (override_stipple)
1169         stipple = override_stipple;
1170       else
1171         stipple = priv->stipple;
1172       
1173       if (!stipple)
1174         fill = GDK_SOLID;
1175       break;
1176     }
1177   
1178   switch (fill)
1179     {
1180     case GDK_SOLID:
1181       gdk_cairo_set_source_color (cr, &foreground);
1182       break;
1183     case GDK_TILED:
1184       tile_surface = _gdk_drawable_ref_cairo_surface (priv->tile);
1185       break;
1186     case GDK_STIPPLED:
1187       tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, NULL);
1188       break;
1189     case GDK_OPAQUE_STIPPLED:
1190       tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, &background);
1191       break;
1192     }
1193
1194   /* Tiles, stipples, and clip regions are all specified in device space,
1195    * not user space. For the clip region, we can simply change the matrix,
1196    * clip, then clip back, but for the source pattern, we need to
1197    * compute the right matrix.
1198    *
1199    * What we want is:
1200    *
1201    *     CTM_inverse * Pattern_matrix = Translate(- ts_x, - ts_y)
1202    *
1203    * (So that ts_x, ts_y in device space is taken to 0,0 in pattern
1204    * space). So, pattern_matrix = CTM * Translate(- ts_x, - tx_y);
1205    */
1206
1207   if (tile_surface)
1208     {
1209       cairo_pattern_t *pattern = cairo_pattern_create_for_surface (tile_surface);
1210       cairo_matrix_t user_to_device;
1211       cairo_matrix_t user_to_pattern;
1212       cairo_matrix_t device_to_pattern;
1213
1214       cairo_get_matrix (cr, &user_to_device);
1215       cairo_matrix_init_translate (&device_to_pattern,
1216                                    - gc->ts_x_origin, - gc->ts_y_origin);
1217       cairo_matrix_multiply (&user_to_pattern,
1218                              &user_to_device, &device_to_pattern);
1219       
1220       cairo_pattern_set_matrix (pattern, &user_to_pattern);
1221       cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
1222       cairo_set_source (cr, pattern);
1223       
1224       cairo_surface_destroy (tile_surface);
1225       cairo_pattern_destroy (pattern);
1226     }
1227
1228   if (!gc_changed)
1229     return;
1230
1231   cairo_reset_clip (cr);
1232   if (priv->clip_region)
1233     {
1234       cairo_save (cr);
1235
1236       cairo_identity_matrix (cr);
1237       cairo_translate (cr, gc->clip_x_origin, gc->clip_y_origin);
1238
1239       cairo_new_path (cr);
1240       gdk_cairo_region (cr, priv->clip_region);
1241
1242       cairo_restore (cr);
1243
1244       cairo_clip (cr);
1245     }
1246 }
1247
1248
1249 #define __GDK_GC_C__
1250 #include "gdkaliasdef.c"