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   guint32 region_tag_applied;
47   int region_tag_offset_x;
48   int region_tag_offset_y;
49 
50   GdkRegion *old_clip_region;
51   GdkPixmap *old_clip_mask;
52 
53   GdkBitmap *stipple;
54   GdkPixmap *tile;
55 
56   GdkPixmap *clip_mask;
57 
58   guint32 fg_pixel;
59   guint32 bg_pixel;
60 
61   guint subwindow_mode : 1;
62   guint fill : 2;
63   guint exposures : 2;
64 };
65 
66 #define GDK_GC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_GC, GdkGCPrivate))
67 
G_DEFINE_TYPE(GdkGC,gdk_gc,G_TYPE_OBJECT)68 G_DEFINE_TYPE (GdkGC, gdk_gc, G_TYPE_OBJECT)
69 
70 static void
71 gdk_gc_class_init (GdkGCClass *class)
72 {
73   GObjectClass *object_class = G_OBJECT_CLASS (class);
74 
75   object_class->finalize = gdk_gc_finalize;
76 
77   g_type_class_add_private (object_class, sizeof (GdkGCPrivate));
78 }
79 
80 static void
gdk_gc_init(GdkGC * gc)81 gdk_gc_init (GdkGC *gc)
82 {
83   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
84 
85   priv->fill = GDK_SOLID;
86 
87   /* These are the default X11 value, which we match. They are clearly
88    * wrong for TrueColor displays, so apps have to change them.
89    */
90   priv->fg_pixel = 0;
91   priv->bg_pixel = 1;
92 }
93 
94 /**
95  * gdk_gc_new:
96  * @drawable: a #GdkDrawable. The created GC must always be used
97  *   with drawables of the same depth as this one.
98  *
99  * Create a new graphics context with default values.
100  *
101  * Returns: the new graphics context.
102  *
103  * Deprecated: 2.22: Use Cairo for rendering.
104  **/
105 GdkGC*
gdk_gc_new(GdkDrawable * drawable)106 gdk_gc_new (GdkDrawable *drawable)
107 {
108   g_return_val_if_fail (drawable != NULL, NULL);
109 
110   return gdk_gc_new_with_values (drawable, NULL, 0);
111 }
112 
113 /**
114  * gdk_gc_new_with_values:
115  * @drawable: a #GdkDrawable. The created GC must always be used
116  *   with drawables of the same depth as this one.
117  * @values: a structure containing initial values for the GC.
118  * @values_mask: a bit mask indicating which fields in @values
119  *   are set.
120  *
121  * Create a new GC with the given initial values.
122  *
123  * Return value: the new graphics context.
124  *
125  * Deprecated: 2.22: Use Cairo for rendering.
126  **/
127 GdkGC*
gdk_gc_new_with_values(GdkDrawable * drawable,GdkGCValues * values,GdkGCValuesMask values_mask)128 gdk_gc_new_with_values (GdkDrawable	*drawable,
129 			GdkGCValues	*values,
130 			GdkGCValuesMask	 values_mask)
131 {
132   g_return_val_if_fail (drawable != NULL, NULL);
133 
134   return GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable,
135 						       values,
136 						       values_mask);
137 }
138 
139 /**
140  * _gdk_gc_init:
141  * @gc: a #GdkGC
142  * @drawable: a #GdkDrawable.
143  * @values: a structure containing initial values for the GC.
144  * @values_mask: a bit mask indicating which fields in @values
145  *   are set.
146  *
147  * Does initialization of the generic portions of a #GdkGC
148  * created with the specified values and values_mask. This
149  * should be called out of the implementation of
150  * GdkDrawable.create_gc() immediately after creating the
151  * #GdkGC object.
152  *
153  * Deprecated: 2.22: Use Cairo for rendering.
154  **/
155 void
_gdk_gc_init(GdkGC * gc,GdkDrawable * drawable,GdkGCValues * values,GdkGCValuesMask values_mask)156 _gdk_gc_init (GdkGC           *gc,
157 	      GdkDrawable     *drawable,
158 	      GdkGCValues     *values,
159 	      GdkGCValuesMask  values_mask)
160 {
161   GdkGCPrivate *priv;
162 
163   g_return_if_fail (GDK_IS_GC (gc));
164 
165   priv = GDK_GC_GET_PRIVATE (gc);
166 
167   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
168     gc->clip_x_origin = values->clip_x_origin;
169   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
170     gc->clip_y_origin = values->clip_y_origin;
171   if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask)
172     priv->clip_mask = g_object_ref (values->clip_mask);
173   if (values_mask & GDK_GC_TS_X_ORIGIN)
174     gc->ts_x_origin = values->ts_x_origin;
175   if (values_mask & GDK_GC_TS_Y_ORIGIN)
176     gc->ts_y_origin = values->ts_y_origin;
177   if (values_mask & GDK_GC_FILL)
178     priv->fill = values->fill;
179   if (values_mask & GDK_GC_STIPPLE)
180     {
181       priv->stipple = values->stipple;
182       if (priv->stipple)
183 	g_object_ref (priv->stipple);
184     }
185   if (values_mask & GDK_GC_TILE)
186     {
187       priv->tile = values->tile;
188       if (priv->tile)
189 	g_object_ref (priv->tile);
190     }
191   if (values_mask & GDK_GC_FOREGROUND)
192     priv->fg_pixel = values->foreground.pixel;
193   if (values_mask & GDK_GC_BACKGROUND)
194     priv->bg_pixel = values->background.pixel;
195   if (values_mask & GDK_GC_SUBWINDOW)
196     priv->subwindow_mode = values->subwindow_mode;
197   if (values_mask & GDK_GC_EXPOSURES)
198     priv->exposures = values->graphics_exposures;
199   else
200     priv->exposures = TRUE;
201 
202   gc->colormap = gdk_drawable_get_colormap (drawable);
203   if (gc->colormap)
204     g_object_ref (gc->colormap);
205 }
206 
207 static void
gdk_gc_finalize(GObject * object)208 gdk_gc_finalize (GObject *object)
209 {
210   GdkGC *gc = GDK_GC (object);
211   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
212 
213   if (priv->clip_region)
214     gdk_region_destroy (priv->clip_region);
215   if (priv->old_clip_region)
216     gdk_region_destroy (priv->old_clip_region);
217   if (priv->clip_mask)
218     g_object_unref (priv->clip_mask);
219   if (priv->old_clip_mask)
220     g_object_unref (priv->old_clip_mask);
221   if (gc->colormap)
222     g_object_unref (gc->colormap);
223   if (priv->tile)
224     g_object_unref (priv->tile);
225   if (priv->stipple)
226     g_object_unref (priv->stipple);
227 
228   G_OBJECT_CLASS (gdk_gc_parent_class)->finalize (object);
229 }
230 
231 /**
232  * gdk_gc_ref:
233  * @gc: a #GdkGC
234  *
235  * Deprecated function; use g_object_ref() instead.
236  *
237  * Return value: the gc.
238  *
239  * Deprecated: 2.0: Use g_object_ref() instead.
240  **/
241 GdkGC *
gdk_gc_ref(GdkGC * gc)242 gdk_gc_ref (GdkGC *gc)
243 {
244   return (GdkGC *) g_object_ref (gc);
245 }
246 
247 /**
248  * gdk_gc_unref:
249  * @gc: a #GdkGC
250  *
251  * Decrement the reference count of @gc.
252  *
253  * Deprecated: 2.0: Use g_object_unref() instead.
254  **/
255 void
gdk_gc_unref(GdkGC * gc)256 gdk_gc_unref (GdkGC *gc)
257 {
258   g_object_unref (gc);
259 }
260 
261 /**
262  * gdk_gc_get_values:
263  * @gc:  a #GdkGC.
264  * @values: the #GdkGCValues structure in which to store the results.
265  *
266  * Retrieves the current values from a graphics context. Note that
267  * only the pixel values of the @values->foreground and @values->background
268  * are filled, use gdk_colormap_query_color() to obtain the rgb values
269  * if you need them.
270  *
271  * Deprecated: 2.22: Use Cairo for rendering.
272  **/
273 void
gdk_gc_get_values(GdkGC * gc,GdkGCValues * values)274 gdk_gc_get_values (GdkGC       *gc,
275 		   GdkGCValues *values)
276 {
277   g_return_if_fail (GDK_IS_GC (gc));
278   g_return_if_fail (values != NULL);
279 
280   GDK_GC_GET_CLASS (gc)->get_values (gc, values);
281 }
282 
283 /**
284  * gdk_gc_set_values:
285  * @gc: a #GdkGC
286  * @values: struct containing the new values
287  * @values_mask: mask indicating which struct fields are to be used
288  *
289  * Sets attributes of a graphics context in bulk. For each flag set in
290  * @values_mask, the corresponding field will be read from @values and
291  * set as the new value for @gc. If you're only setting a few values
292  * on @gc, calling individual "setter" functions is likely more
293  * convenient.
294  *
295  * Deprecated: 2.22: Use Cairo for rendering.
296  **/
297 void
gdk_gc_set_values(GdkGC * gc,GdkGCValues * values,GdkGCValuesMask values_mask)298 gdk_gc_set_values (GdkGC           *gc,
299 		   GdkGCValues	   *values,
300 		   GdkGCValuesMask  values_mask)
301 {
302   GdkGCPrivate *priv;
303 
304   g_return_if_fail (GDK_IS_GC (gc));
305   g_return_if_fail (values != NULL);
306 
307   priv = GDK_GC_GET_PRIVATE (gc);
308 
309   if ((values_mask & GDK_GC_CLIP_X_ORIGIN) ||
310       (values_mask & GDK_GC_CLIP_Y_ORIGIN) ||
311       (values_mask & GDK_GC_CLIP_MASK) ||
312       (values_mask & GDK_GC_SUBWINDOW))
313     _gdk_gc_remove_drawable_clip (gc);
314 
315   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
316     gc->clip_x_origin = values->clip_x_origin;
317   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
318     gc->clip_y_origin = values->clip_y_origin;
319   if (values_mask & GDK_GC_TS_X_ORIGIN)
320     gc->ts_x_origin = values->ts_x_origin;
321   if (values_mask & GDK_GC_TS_Y_ORIGIN)
322     gc->ts_y_origin = values->ts_y_origin;
323   if (values_mask & GDK_GC_CLIP_MASK)
324     {
325       if (priv->clip_mask)
326 	{
327 	  g_object_unref (priv->clip_mask);
328 	  priv->clip_mask = NULL;
329 	}
330       if (values->clip_mask)
331 	priv->clip_mask = g_object_ref (values->clip_mask);
332 
333       if (priv->clip_region)
334 	{
335 	  gdk_region_destroy (priv->clip_region);
336 	  priv->clip_region = NULL;
337 	}
338     }
339   if (values_mask & GDK_GC_FILL)
340     priv->fill = values->fill;
341   if (values_mask & GDK_GC_STIPPLE)
342     {
343       if (priv->stipple != values->stipple)
344 	{
345 	  if (priv->stipple)
346 	    g_object_unref (priv->stipple);
347 	  priv->stipple = values->stipple;
348 	  if (priv->stipple)
349 	    g_object_ref (priv->stipple);
350 	}
351     }
352   if (values_mask & GDK_GC_TILE)
353     {
354       if (priv->tile != values->tile)
355 	{
356 	  if (priv->tile)
357 	    g_object_unref (priv->tile);
358 	  priv->tile = values->tile;
359 	  if (priv->tile)
360 	    g_object_ref (priv->tile);
361 	}
362     }
363   if (values_mask & GDK_GC_FOREGROUND)
364     priv->fg_pixel = values->foreground.pixel;
365   if (values_mask & GDK_GC_BACKGROUND)
366     priv->bg_pixel = values->background.pixel;
367   if (values_mask & GDK_GC_SUBWINDOW)
368     priv->subwindow_mode = values->subwindow_mode;
369   if (values_mask & GDK_GC_EXPOSURES)
370     priv->exposures = values->graphics_exposures;
371 
372   GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask);
373 }
374 
375 /**
376  * gdk_gc_set_foreground:
377  * @gc: a #GdkGC.
378  * @color: the new foreground color.
379  *
380  * Sets the foreground color for a graphics context.
381  * Note that this function uses @color->pixel, use
382  * gdk_gc_set_rgb_fg_color() to specify the foreground
383  * color as red, green, blue components.
384  *
385  * Deprecated: 2.22: Use gdk_cairo_set_source_color() to use a #GdkColor
386  * as the source in Cairo.
387  **/
388 void
gdk_gc_set_foreground(GdkGC * gc,const GdkColor * color)389 gdk_gc_set_foreground (GdkGC	      *gc,
390 		       const GdkColor *color)
391 {
392   GdkGCValues values;
393 
394   g_return_if_fail (GDK_IS_GC (gc));
395   g_return_if_fail (color != NULL);
396 
397   values.foreground = *color;
398   gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND);
399 }
400 
401 /**
402  * gdk_gc_set_background:
403  * @gc: a #GdkGC.
404  * @color: the new background color.
405  *
406  * Sets the background color for a graphics context.
407  * Note that this function uses @color->pixel, use
408  * gdk_gc_set_rgb_bg_color() to specify the background
409  * color as red, green, blue components.
410  *
411  * Deprecated: 2.22: Use gdk_cairo_set_source_color() to use a #GdkColor
412  * as the source in Cairo. Note that if you want to draw a background and a
413  * foreground in Cairo, you need to call drawing functions (like cairo_fill())
414  * twice.
415  **/
416 void
gdk_gc_set_background(GdkGC * gc,const GdkColor * color)417 gdk_gc_set_background (GdkGC	      *gc,
418 		       const GdkColor *color)
419 {
420   GdkGCValues values;
421 
422   g_return_if_fail (GDK_IS_GC (gc));
423   g_return_if_fail (color != NULL);
424 
425   values.background = *color;
426   gdk_gc_set_values (gc, &values, GDK_GC_BACKGROUND);
427 }
428 
429 /**
430  * gdk_gc_set_font:
431  * @gc: a #GdkGC.
432  * @font: the new font.
433  *
434  * Sets the font for a graphics context. (Note that
435  * all text-drawing functions in GDK take a @font
436  * argument; the value set here is used when that
437  * argument is %NULL.)
438  **/
439 void
gdk_gc_set_font(GdkGC * gc,GdkFont * font)440 gdk_gc_set_font (GdkGC	 *gc,
441 		 GdkFont *font)
442 {
443   GdkGCValues values;
444 
445   g_return_if_fail (GDK_IS_GC (gc));
446   g_return_if_fail (font != NULL);
447 
448   values.font = font;
449   gdk_gc_set_values (gc, &values, GDK_GC_FONT);
450 }
451 
452 /**
453  * gdk_gc_set_function:
454  * @gc: a #GdkGC.
455  * @function: the #GdkFunction to use
456  *
457  * Determines how the current pixel values and the
458  * pixel values being drawn are combined to produce
459  * the final pixel values.
460  *
461  * Deprecated: 2.22: Use cairo_set_operator() with Cairo.
462  **/
463 void
gdk_gc_set_function(GdkGC * gc,GdkFunction function)464 gdk_gc_set_function (GdkGC	 *gc,
465 		     GdkFunction  function)
466 {
467   GdkGCValues values;
468 
469   g_return_if_fail (GDK_IS_GC (gc));
470 
471   values.function = function;
472   gdk_gc_set_values (gc, &values, GDK_GC_FUNCTION);
473 }
474 
475 /**
476  * gdk_gc_set_fill:
477  * @gc: a #GdkGC.
478  * @fill: the new fill mode.
479  *
480  * Set the fill mode for a graphics context.
481  *
482  * Deprecated: 2.22: You can achieve tiling in Cairo by using
483  * cairo_pattern_set_extend() on the source. For stippling, see the
484  * deprecation comments on gdk_gc_set_stipple().
485  **/
486 void
gdk_gc_set_fill(GdkGC * gc,GdkFill fill)487 gdk_gc_set_fill (GdkGC	 *gc,
488 		 GdkFill  fill)
489 {
490   GdkGCValues values;
491 
492   g_return_if_fail (GDK_IS_GC (gc));
493 
494   values.fill = fill;
495   gdk_gc_set_values (gc, &values, GDK_GC_FILL);
496 }
497 
498 /**
499  * gdk_gc_set_tile:
500  * @gc:  a #GdkGC.
501  * @tile:  the new tile pixmap.
502  *
503  * Set a tile pixmap for a graphics context.
504  * This will only be used if the fill mode
505  * is %GDK_TILED.
506  *
507  * Deprecated: 2.22: The following code snippet sets a tiling #GdkPixmap
508  * as the source in Cairo:
509  * |[gdk_cairo_set_source_pixmap (cr, tile, ts_origin_x, ts_origin_y);
510  * cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);]|
511  **/
512 void
gdk_gc_set_tile(GdkGC * gc,GdkPixmap * tile)513 gdk_gc_set_tile (GdkGC	   *gc,
514 		 GdkPixmap *tile)
515 {
516   GdkGCValues values;
517 
518   g_return_if_fail (GDK_IS_GC (gc));
519 
520   values.tile = tile;
521   gdk_gc_set_values (gc, &values, GDK_GC_TILE);
522 }
523 
524 /**
525  * gdk_gc_set_stipple:
526  * @gc: a #GdkGC.
527  * @stipple: the new stipple bitmap.
528  *
529  * Set the stipple bitmap for a graphics context. The
530  * stipple will only be used if the fill mode is
531  * %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED.
532  *
533  * Deprecated: 2.22: Stippling has no direct replacement in Cairo. If you
534  * want to achieve an identical look, you can use the stipple bitmap as a
535  * mask. Most likely, this involves rendering the source to an intermediate
536  * surface using cairo_push_group() first, so that you can then use
537  * cairo_mask() to achieve the stippled look.
538  **/
539 void
gdk_gc_set_stipple(GdkGC * gc,GdkPixmap * stipple)540 gdk_gc_set_stipple (GdkGC     *gc,
541 		    GdkPixmap *stipple)
542 {
543   GdkGCValues values;
544 
545   g_return_if_fail (GDK_IS_GC (gc));
546 
547   values.stipple = stipple;
548   gdk_gc_set_values (gc, &values, GDK_GC_STIPPLE);
549 }
550 
551 /**
552  * gdk_gc_set_ts_origin:
553  * @gc:  a #GdkGC.
554  * @x: the x-coordinate of the origin.
555  * @y: the y-coordinate of the origin.
556  *
557  * Set the origin when using tiles or stipples with
558  * the GC. The tile or stipple will be aligned such
559  * that the upper left corner of the tile or stipple
560  * will coincide with this point.
561  *
562  * Deprecated: 2.22: You can set the origin for tiles and stipples in Cairo
563  * by changing the source's matrix using cairo_pattern_set_matrix(). Or you
564  * can specify it with gdk_cairo_set_source_pixmap() as shown in the example
565  * for gdk_gc_set_tile().
566  **/
567 void
gdk_gc_set_ts_origin(GdkGC * gc,gint x,gint y)568 gdk_gc_set_ts_origin (GdkGC *gc,
569 		      gint   x,
570 		      gint   y)
571 {
572   GdkGCValues values;
573 
574   g_return_if_fail (GDK_IS_GC (gc));
575 
576   values.ts_x_origin = x;
577   values.ts_y_origin = y;
578 
579   gdk_gc_set_values (gc, &values,
580 		     GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
581 }
582 
583 /**
584  * gdk_gc_set_clip_origin:
585  * @gc: a #GdkGC.
586  * @x: the x-coordinate of the origin.
587  * @y: the y-coordinate of the origin.
588  *
589  * Sets the origin of the clip mask. The coordinates are
590  * interpreted relative to the upper-left corner of
591  * the destination drawable of the current operation.
592  *
593  * Deprecated: 2.22: Use cairo_translate() before applying the clip path in
594  * Cairo.
595  **/
596 void
gdk_gc_set_clip_origin(GdkGC * gc,gint x,gint y)597 gdk_gc_set_clip_origin (GdkGC *gc,
598 			gint   x,
599 			gint   y)
600 {
601   GdkGCValues values;
602 
603   g_return_if_fail (GDK_IS_GC (gc));
604 
605   values.clip_x_origin = x;
606   values.clip_y_origin = y;
607 
608   gdk_gc_set_values (gc, &values,
609 		     GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
610 }
611 
612 /**
613  * gdk_gc_set_clip_mask:
614  * @gc: the #GdkGC.
615  * @mask: a bitmap.
616  *
617  * Sets the clip mask for a graphics context from a bitmap.
618  * The clip mask is interpreted relative to the clip
619  * origin. (See gdk_gc_set_clip_origin()).
620  *
621  * Deprecated: 2.22: Use cairo_mask() instead.
622  **/
623 void
gdk_gc_set_clip_mask(GdkGC * gc,GdkBitmap * mask)624 gdk_gc_set_clip_mask (GdkGC	*gc,
625 		      GdkBitmap *mask)
626 {
627   GdkGCValues values;
628 
629   g_return_if_fail (GDK_IS_GC (gc));
630 
631   values.clip_mask = mask;
632   gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK);
633 }
634 
635 /* Takes ownership of passed in region */
636 static void
_gdk_gc_set_clip_region_real(GdkGC * gc,GdkRegion * region,gboolean reset_origin)637 _gdk_gc_set_clip_region_real (GdkGC     *gc,
638 			      GdkRegion *region,
639 			      gboolean reset_origin)
640 {
641   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
642 
643   if (priv->clip_mask)
644     {
645       g_object_unref (priv->clip_mask);
646       priv->clip_mask = NULL;
647     }
648 
649   if (priv->clip_region)
650     gdk_region_destroy (priv->clip_region);
651 
652   priv->clip_region = region;
653 
654   _gdk_windowing_gc_set_clip_region (gc, region, reset_origin);
655 }
656 
657 /* Doesn't copy region, allows not to reset origin */
658 void
_gdk_gc_set_clip_region_internal(GdkGC * gc,GdkRegion * region,gboolean reset_origin)659 _gdk_gc_set_clip_region_internal (GdkGC     *gc,
660 				  GdkRegion *region,
661 				  gboolean reset_origin)
662 {
663   _gdk_gc_remove_drawable_clip (gc);
664   _gdk_gc_set_clip_region_real (gc, region, reset_origin);
665 }
666 
667 
668 void
_gdk_gc_add_drawable_clip(GdkGC * gc,guint32 region_tag,GdkRegion * region,int offset_x,int offset_y)669 _gdk_gc_add_drawable_clip (GdkGC     *gc,
670 			   guint32    region_tag,
671 			   GdkRegion *region,
672 			   int        offset_x,
673 			   int        offset_y)
674 {
675   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
676 
677   if (priv->region_tag_applied == region_tag &&
678       offset_x == priv->region_tag_offset_x &&
679       offset_y == priv->region_tag_offset_y)
680     return; /* Already appied this drawable region */
681 
682   if (priv->region_tag_applied)
683     _gdk_gc_remove_drawable_clip (gc);
684 
685   region = gdk_region_copy (region);
686   if (offset_x != 0 || offset_y != 0)
687     gdk_region_offset (region, offset_x, offset_y);
688 
689   if (priv->clip_mask)
690     {
691       int w, h;
692       GdkPixmap *new_mask;
693       GdkGC *tmp_gc;
694       GdkColor black = {0, 0, 0, 0};
695       GdkRectangle r;
696       GdkOverlapType overlap;
697 
698       gdk_drawable_get_size (priv->clip_mask, &w, &h);
699 
700       r.x = 0;
701       r.y = 0;
702       r.width = w;
703       r.height = h;
704 
705       /* Its quite common to expose areas that are completely in or outside
706        * the region, so we try to avoid allocating bitmaps that are just fully
707        * set or completely unset.
708        */
709       overlap = gdk_region_rect_in (region, &r);
710       if (overlap == GDK_OVERLAP_RECTANGLE_PART)
711 	{
712 	   /* The region and the mask intersect, create a new clip mask that
713 	      includes both areas */
714 	  priv->old_clip_mask = g_object_ref (priv->clip_mask);
715 	  new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1);
716 	  tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE);
717 
718 	  gdk_gc_set_foreground (tmp_gc, &black);
719 	  gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1);
720 	  _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */
721 	  gdk_draw_drawable  (new_mask,
722 			      tmp_gc,
723 			      priv->old_clip_mask,
724 			      0, 0,
725 			      0, 0,
726 			      -1, -1);
727 	  gdk_gc_set_clip_region (tmp_gc, NULL);
728 	  gdk_gc_set_clip_mask (gc, new_mask);
729 	  g_object_unref (new_mask);
730 	}
731       else if (overlap == GDK_OVERLAP_RECTANGLE_OUT)
732 	{
733 	  /* No intersection, set empty clip region */
734 	  GdkRegion *empty = gdk_region_new ();
735 
736 	  gdk_region_destroy (region);
737 	  priv->old_clip_mask = g_object_ref (priv->clip_mask);
738 	  priv->clip_region = empty;
739 	  _gdk_windowing_gc_set_clip_region (gc, empty, FALSE);
740 	}
741       else
742 	{
743 	  /* Completely inside region, don't set unnecessary clip */
744 	  gdk_region_destroy (region);
745 	  return;
746 	}
747     }
748   else
749     {
750       priv->old_clip_region = priv->clip_region;
751       priv->clip_region = region;
752       if (priv->old_clip_region)
753 	gdk_region_intersect (region, priv->old_clip_region);
754 
755       _gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE);
756     }
757 
758   priv->region_tag_applied = region_tag;
759   priv->region_tag_offset_x = offset_x;
760   priv->region_tag_offset_y = offset_y;
761 }
762 
763 void
_gdk_gc_remove_drawable_clip(GdkGC * gc)764 _gdk_gc_remove_drawable_clip (GdkGC *gc)
765 {
766   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
767 
768   if (priv->region_tag_applied)
769     {
770       priv->region_tag_applied = 0;
771       if (priv->old_clip_mask)
772 	{
773 	  gdk_gc_set_clip_mask (gc, priv->old_clip_mask);
774 	  g_object_unref (priv->old_clip_mask);
775 	  priv->old_clip_mask = NULL;
776 
777 	  if (priv->clip_region)
778 	    {
779 	      g_object_unref (priv->clip_region);
780 	      priv->clip_region = NULL;
781 	    }
782 	}
783       else
784 	{
785 	  _gdk_gc_set_clip_region_real (gc, priv->old_clip_region, FALSE);
786 	  priv->old_clip_region = NULL;
787 	}
788     }
789 }
790 
791 /**
792  * gdk_gc_set_clip_rectangle:
793  * @gc: a #GdkGC.
794  * @rectangle: the rectangle to clip to.
795  *
796  * Sets the clip mask for a graphics context from a
797  * rectangle. The clip mask is interpreted relative to the clip
798  * origin. (See gdk_gc_set_clip_origin()).
799  *
800  * Deprecated: 2.22: Use cairo_rectangle() and cairo_clip() in Cairo.
801  **/
802 void
gdk_gc_set_clip_rectangle(GdkGC * gc,const GdkRectangle * rectangle)803 gdk_gc_set_clip_rectangle (GdkGC              *gc,
804 			   const GdkRectangle *rectangle)
805 {
806   GdkRegion *region;
807 
808   g_return_if_fail (GDK_IS_GC (gc));
809 
810   _gdk_gc_remove_drawable_clip (gc);
811 
812   if (rectangle)
813     region = gdk_region_rectangle (rectangle);
814   else
815     region = NULL;
816 
817   _gdk_gc_set_clip_region_real (gc, region, TRUE);
818 }
819 
820 /**
821  * gdk_gc_set_clip_region:
822  * @gc: a #GdkGC.
823  * @region: the #GdkRegion.
824  *
825  * Sets the clip mask for a graphics context from a region structure.
826  * The clip mask is interpreted relative to the clip origin. (See
827  * gdk_gc_set_clip_origin()).
828  *
829  * Deprecated: 2.22: Use gdk_cairo_region() and cairo_clip() in Cairo.
830  **/
831 void
gdk_gc_set_clip_region(GdkGC * gc,const GdkRegion * region)832 gdk_gc_set_clip_region (GdkGC           *gc,
833 			const GdkRegion *region)
834 {
835   GdkRegion *copy;
836 
837   g_return_if_fail (GDK_IS_GC (gc));
838 
839   _gdk_gc_remove_drawable_clip (gc);
840 
841   if (region)
842     copy = gdk_region_copy (region);
843   else
844     copy = NULL;
845 
846   _gdk_gc_set_clip_region_real (gc, copy, TRUE);
847 }
848 
849 /**
850  * _gdk_gc_get_clip_region:
851  * @gc: a #GdkGC
852  *
853  * Gets the current clip region for @gc, if any.
854  *
855  * Return value: the clip region for the GC, or %NULL.
856  *   (if a clip mask is set, the return will be %NULL)
857  *   This value is owned by the GC and must not be freed.
858  **/
859 GdkRegion *
_gdk_gc_get_clip_region(GdkGC * gc)860 _gdk_gc_get_clip_region (GdkGC *gc)
861 {
862   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
863 
864   return GDK_GC_GET_PRIVATE (gc)->clip_region;
865 }
866 
867 /**
868  * _gdk_gc_get_clip_mask:
869  * @gc: a #GdkGC
870  *
871  * Gets the current clip mask for @gc, if any.
872  *
873  * Return value: the clip mask for the GC, or %NULL.
874  *   (if a clip region is set, the return will be %NULL)
875  *   This value is owned by the GC and must not be freed.
876  **/
877 GdkBitmap *
_gdk_gc_get_clip_mask(GdkGC * gc)878 _gdk_gc_get_clip_mask (GdkGC *gc)
879 {
880   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
881 
882   return GDK_GC_GET_PRIVATE (gc)->clip_mask;
883 }
884 
885 /**
886  * _gdk_gc_get_fill:
887  * @gc: a #GdkGC
888  *
889  * Gets the current file style for the GC
890  *
891  * Return value: the file style for the GC
892  **/
893 GdkFill
_gdk_gc_get_fill(GdkGC * gc)894 _gdk_gc_get_fill (GdkGC *gc)
895 {
896   g_return_val_if_fail (GDK_IS_GC (gc), GDK_SOLID);
897 
898   return GDK_GC_GET_PRIVATE (gc)->fill;
899 }
900 
901 gboolean
_gdk_gc_get_exposures(GdkGC * gc)902 _gdk_gc_get_exposures (GdkGC *gc)
903 {
904   g_return_val_if_fail (GDK_IS_GC (gc), FALSE);
905 
906   return GDK_GC_GET_PRIVATE (gc)->exposures;
907 }
908 
909 /**
910  * _gdk_gc_get_tile:
911  * @gc: a #GdkGC
912  *
913  * Gets the tile pixmap for @gc, if any
914  *
915  * Return value: the tile set on the GC, or %NULL. The
916  *   value is owned by the GC and must not be freed.
917  **/
918 GdkPixmap *
_gdk_gc_get_tile(GdkGC * gc)919 _gdk_gc_get_tile (GdkGC *gc)
920 {
921   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
922 
923   return GDK_GC_GET_PRIVATE (gc)->tile;
924 }
925 
926 /**
927  * _gdk_gc_get_stipple:
928  * @gc: a #GdkGC
929  *
930  * Gets the stipple pixmap for @gc, if any
931  *
932  * Return value: the stipple set on the GC, or %NULL. The
933  *   value is owned by the GC and must not be freed.
934  **/
935 GdkBitmap *
_gdk_gc_get_stipple(GdkGC * gc)936 _gdk_gc_get_stipple (GdkGC *gc)
937 {
938   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
939 
940   return GDK_GC_GET_PRIVATE (gc)->stipple;
941 }
942 
943 /**
944  * _gdk_gc_get_fg_pixel:
945  * @gc: a #GdkGC
946  *
947  * Gets the foreground pixel value for @gc. If the
948  * foreground pixel has never been set, returns the
949  * default value 0.
950  *
951  * Return value: the foreground pixel value of the GC
952  **/
953 guint32
_gdk_gc_get_fg_pixel(GdkGC * gc)954 _gdk_gc_get_fg_pixel (GdkGC *gc)
955 {
956   g_return_val_if_fail (GDK_IS_GC (gc), 0);
957 
958   return GDK_GC_GET_PRIVATE (gc)->fg_pixel;
959 }
960 
961 /**
962  * _gdk_gc_get_bg_pixel:
963  * @gc: a #GdkGC
964  *
965  * Gets the background pixel value for @gc.If the
966  * foreground pixel has never been set, returns the
967  * default value 1.
968  *
969  * Return value: the foreground pixel value of the GC
970  **/
971 guint32
_gdk_gc_get_bg_pixel(GdkGC * gc)972 _gdk_gc_get_bg_pixel (GdkGC *gc)
973 {
974   g_return_val_if_fail (GDK_IS_GC (gc), 0);
975 
976   return GDK_GC_GET_PRIVATE (gc)->bg_pixel;
977 }
978 
979 /**
980  * gdk_gc_set_subwindow:
981  * @gc: a #GdkGC.
982  * @mode: the subwindow mode.
983  *
984  * Sets how drawing with this GC on a window will affect child
985  * windows of that window.
986  *
987  * Deprecated: 2.22: There is no replacement. If you need to control
988  * subwindows, you must use drawing operations of the underlying window
989  * system manually. Cairo will always use %GDK_INCLUDE_INFERIORS on sources
990  * and masks and %GDK_CLIP_BY_CHILDREN on targets.
991  **/
992 void
gdk_gc_set_subwindow(GdkGC * gc,GdkSubwindowMode mode)993 gdk_gc_set_subwindow (GdkGC	       *gc,
994 		      GdkSubwindowMode	mode)
995 {
996   GdkGCValues values;
997   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
998 
999   g_return_if_fail (GDK_IS_GC (gc));
1000 
1001   /* This could get called a lot to reset the subwindow mode in
1002      the client side clipping, so bail out early */
1003   if (priv->subwindow_mode == mode)
1004     return;
1005 
1006   values.subwindow_mode = mode;
1007   gdk_gc_set_values (gc, &values, GDK_GC_SUBWINDOW);
1008 }
1009 
1010 GdkSubwindowMode
_gdk_gc_get_subwindow(GdkGC * gc)1011 _gdk_gc_get_subwindow (GdkGC *gc)
1012 {
1013   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
1014 
1015   return priv->subwindow_mode;
1016 }
1017 
1018 /**
1019  * gdk_gc_set_exposures:
1020  * @gc: a #GdkGC.
1021  * @exposures: if %TRUE, exposure events will be generated.
1022  *
1023  * Sets whether copying non-visible portions of a drawable
1024  * using this graphics context generate exposure events
1025  * for the corresponding regions of the destination
1026  * drawable. (See gdk_draw_drawable()).
1027  *
1028  * Deprecated: 2.22: There is no replacement. If you need to control
1029  * exposures, you must use drawing operations of the underlying window
1030  * system or use gdk_window_invalidate_rect(). Cairo will never
1031  * generate exposures.
1032  **/
1033 void
gdk_gc_set_exposures(GdkGC * gc,gboolean exposures)1034 gdk_gc_set_exposures (GdkGC     *gc,
1035 		      gboolean   exposures)
1036 {
1037   GdkGCValues values;
1038 
1039   g_return_if_fail (GDK_IS_GC (gc));
1040 
1041   values.graphics_exposures = exposures;
1042   gdk_gc_set_values (gc, &values, GDK_GC_EXPOSURES);
1043 }
1044 
1045 /**
1046  * gdk_gc_set_line_attributes:
1047  * @gc: a #GdkGC.
1048  * @line_width: the width of lines.
1049  * @line_style: the dash-style for lines.
1050  * @cap_style: the manner in which the ends of lines are drawn.
1051  * @join_style: the in which lines are joined together.
1052  *
1053  * Sets various attributes of how lines are drawn. See
1054  * the corresponding members of #GdkGCValues for full
1055  * explanations of the arguments.
1056  *
1057  * Deprecated: 2.22: Use the Cairo functions cairo_set_line_width(),
1058  * cairo_set_line_join(), cairo_set_line_cap() and cairo_set_dash()
1059  * to affect the stroking behavior in Cairo. Keep in mind that the default
1060  * attributes of a #cairo_t are different from the default attributes of
1061  * a #GdkGC.
1062  **/
1063 void
gdk_gc_set_line_attributes(GdkGC * gc,gint line_width,GdkLineStyle line_style,GdkCapStyle cap_style,GdkJoinStyle join_style)1064 gdk_gc_set_line_attributes (GdkGC	*gc,
1065 			    gint	 line_width,
1066 			    GdkLineStyle line_style,
1067 			    GdkCapStyle	 cap_style,
1068 			    GdkJoinStyle join_style)
1069 {
1070   GdkGCValues values;
1071 
1072   values.line_width = line_width;
1073   values.line_style = line_style;
1074   values.cap_style = cap_style;
1075   values.join_style = join_style;
1076 
1077   gdk_gc_set_values (gc, &values,
1078 		     GDK_GC_LINE_WIDTH |
1079 		     GDK_GC_LINE_STYLE |
1080 		     GDK_GC_CAP_STYLE |
1081 		     GDK_GC_JOIN_STYLE);
1082 }
1083 
1084 /**
1085  * gdk_gc_set_dashes:
1086  * @gc: a #GdkGC.
1087  * @dash_offset: the phase of the dash pattern.
1088  * @dash_list: an array of dash lengths.
1089  * @n: the number of elements in @dash_list.
1090  *
1091  * Sets the way dashed-lines are drawn. Lines will be
1092  * drawn with alternating on and off segments of the
1093  * lengths specified in @dash_list. The manner in
1094  * which the on and off segments are drawn is determined
1095  * by the @line_style value of the GC. (This can
1096  * be changed with gdk_gc_set_line_attributes().)
1097  *
1098  * The @dash_offset defines the phase of the pattern,
1099  * specifying how many pixels into the dash-list the pattern
1100  * should actually begin.
1101  *
1102  * Deprecated: 2.22: Use cairo_set_dash() to set the dash in Cairo.
1103  **/
1104 void
gdk_gc_set_dashes(GdkGC * gc,gint dash_offset,gint8 dash_list[],gint n)1105 gdk_gc_set_dashes (GdkGC *gc,
1106 		   gint	  dash_offset,
1107 		   gint8  dash_list[],
1108 		   gint   n)
1109 {
1110   g_return_if_fail (GDK_IS_GC (gc));
1111   g_return_if_fail (dash_list != NULL);
1112 
1113   GDK_GC_GET_CLASS (gc)->set_dashes (gc, dash_offset, dash_list, n);
1114 }
1115 
1116 /**
1117  * gdk_gc_offset:
1118  * @gc: a #GdkGC
1119  * @x_offset: amount by which to offset the GC in the X direction
1120  * @y_offset: amount by which to offset the GC in the Y direction
1121  *
1122  * Offset attributes such as the clip and tile-stipple origins
1123  * of the GC so that drawing at x - x_offset, y - y_offset with
1124  * the offset GC  has the same effect as drawing at x, y with the original
1125  * GC.
1126  *
1127  * Deprecated: 2.22: There is no direct replacement, as this is just a
1128  * convenience function for gdk_gc_set_ts_origin and gdk_gc_set_clip_origin().
1129  **/
1130 void
gdk_gc_offset(GdkGC * gc,gint x_offset,gint y_offset)1131 gdk_gc_offset (GdkGC *gc,
1132 	       gint   x_offset,
1133 	       gint   y_offset)
1134 {
1135   if (x_offset != 0 || y_offset != 0)
1136     {
1137       GdkGCValues values;
1138 
1139       values.clip_x_origin = gc->clip_x_origin - x_offset;
1140       values.clip_y_origin = gc->clip_y_origin - y_offset;
1141       values.ts_x_origin = gc->ts_x_origin - x_offset;
1142       values.ts_y_origin = gc->ts_y_origin - y_offset;
1143 
1144       gdk_gc_set_values (gc, &values,
1145 			 GDK_GC_CLIP_X_ORIGIN |
1146 			 GDK_GC_CLIP_Y_ORIGIN |
1147 			 GDK_GC_TS_X_ORIGIN |
1148 			 GDK_GC_TS_Y_ORIGIN);
1149     }
1150 }
1151 
1152 /**
1153  * gdk_gc_copy:
1154  * @dst_gc: the destination graphics context.
1155  * @src_gc: the source graphics context.
1156  *
1157  * Copy the set of values from one graphics context
1158  * onto another graphics context.
1159  *
1160  * Deprecated: 2.22: Use Cairo for drawing. cairo_save() and cairo_restore()
1161  * can be helpful in cases where you'd have copied a #GdkGC.
1162  **/
1163 void
gdk_gc_copy(GdkGC * dst_gc,GdkGC * src_gc)1164 gdk_gc_copy (GdkGC *dst_gc,
1165 	     GdkGC *src_gc)
1166 {
1167   GdkGCPrivate *dst_priv, *src_priv;
1168 
1169   g_return_if_fail (GDK_IS_GC (dst_gc));
1170   g_return_if_fail (GDK_IS_GC (src_gc));
1171 
1172   dst_priv = GDK_GC_GET_PRIVATE (dst_gc);
1173   src_priv = GDK_GC_GET_PRIVATE (src_gc);
1174 
1175   _gdk_windowing_gc_copy (dst_gc, src_gc);
1176 
1177   dst_gc->clip_x_origin = src_gc->clip_x_origin;
1178   dst_gc->clip_y_origin = src_gc->clip_y_origin;
1179   dst_gc->ts_x_origin = src_gc->ts_x_origin;
1180   dst_gc->ts_y_origin = src_gc->ts_y_origin;
1181 
1182   if (src_gc->colormap)
1183     g_object_ref (src_gc->colormap);
1184 
1185   if (dst_gc->colormap)
1186     g_object_unref (dst_gc->colormap);
1187 
1188   dst_gc->colormap = src_gc->colormap;
1189 
1190   if (dst_priv->clip_region)
1191     gdk_region_destroy (dst_priv->clip_region);
1192 
1193   if (src_priv->clip_region)
1194     dst_priv->clip_region = gdk_region_copy (src_priv->clip_region);
1195   else
1196     dst_priv->clip_region = NULL;
1197 
1198   dst_priv->region_tag_applied = src_priv->region_tag_applied;
1199 
1200   if (dst_priv->old_clip_region)
1201     gdk_region_destroy (dst_priv->old_clip_region);
1202 
1203   if (src_priv->old_clip_region)
1204     dst_priv->old_clip_region = gdk_region_copy (src_priv->old_clip_region);
1205   else
1206     dst_priv->old_clip_region = NULL;
1207 
1208   if (src_priv->clip_mask)
1209     dst_priv->clip_mask = g_object_ref (src_priv->clip_mask);
1210   else
1211     dst_priv->clip_mask = NULL;
1212 
1213   if (src_priv->old_clip_mask)
1214     dst_priv->old_clip_mask = g_object_ref (src_priv->old_clip_mask);
1215   else
1216     dst_priv->old_clip_mask = NULL;
1217 
1218   dst_priv->fill = src_priv->fill;
1219 
1220   if (dst_priv->stipple)
1221     g_object_unref (dst_priv->stipple);
1222   dst_priv->stipple = src_priv->stipple;
1223   if (dst_priv->stipple)
1224     g_object_ref (dst_priv->stipple);
1225 
1226   if (dst_priv->tile)
1227     g_object_unref (dst_priv->tile);
1228   dst_priv->tile = src_priv->tile;
1229   if (dst_priv->tile)
1230     g_object_ref (dst_priv->tile);
1231 
1232   dst_priv->fg_pixel = src_priv->fg_pixel;
1233   dst_priv->bg_pixel = src_priv->bg_pixel;
1234   dst_priv->subwindow_mode = src_priv->subwindow_mode;
1235   dst_priv->exposures = src_priv->exposures;
1236 }
1237 
1238 /**
1239  * gdk_gc_set_colormap:
1240  * @gc: a #GdkGC
1241  * @colormap: a #GdkColormap
1242  *
1243  * Sets the colormap for the GC to the given colormap. The depth
1244  * of the colormap's visual must match the depth of the drawable
1245  * for which the GC was created.
1246  *
1247  * Deprecated: 2.22: There is no replacement. Cairo handles colormaps
1248  * automatically, so there is no need to care about them.
1249  **/
1250 void
gdk_gc_set_colormap(GdkGC * gc,GdkColormap * colormap)1251 gdk_gc_set_colormap (GdkGC       *gc,
1252 		     GdkColormap *colormap)
1253 {
1254   g_return_if_fail (GDK_IS_GC (gc));
1255   g_return_if_fail (GDK_IS_COLORMAP (colormap));
1256 
1257   if (gc->colormap != colormap)
1258     {
1259       if (gc->colormap)
1260 	g_object_unref (gc->colormap);
1261 
1262       gc->colormap = colormap;
1263       g_object_ref (gc->colormap);
1264     }
1265 
1266 }
1267 
1268 /**
1269  * gdk_gc_get_colormap:
1270  * @gc: a #GdkGC
1271  *
1272  * Retrieves the colormap for a given GC, if it exists.
1273  * A GC will have a colormap if the drawable for which it was created
1274  * has a colormap, or if a colormap was set explicitely with
1275  * gdk_gc_set_colormap.
1276  *
1277  * Return value: the colormap of @gc, or %NULL if @gc doesn't have one.
1278  *
1279  * Deprecated: 2.22: There is no replacement. Cairo handles colormaps
1280  * automatically, so there is no need to care about them.
1281  **/
1282 GdkColormap *
gdk_gc_get_colormap(GdkGC * gc)1283 gdk_gc_get_colormap (GdkGC *gc)
1284 {
1285   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
1286 
1287   return gc->colormap;
1288 }
1289 
1290 static GdkColormap *
gdk_gc_get_colormap_warn(GdkGC * gc)1291 gdk_gc_get_colormap_warn (GdkGC *gc)
1292 {
1293   GdkColormap *colormap = gdk_gc_get_colormap (gc);
1294   if (!colormap)
1295     {
1296       g_warning ("gdk_gc_set_rgb_fg_color() and gdk_gc_set_rgb_bg_color() can\n"
1297 		 "only be used on GC's with a colormap. A GC will have a colormap\n"
1298 		 "if it is created for a drawable with a colormap, or if a\n"
1299 		 "colormap has been set explicitly with gdk_gc_set_colormap.\n");
1300       return NULL;
1301     }
1302 
1303   return colormap;
1304 }
1305 
1306 /**
1307  * gdk_gc_set_rgb_fg_color:
1308  * @gc: a #GdkGC
1309  * @color: an unallocated #GdkColor.
1310  *
1311  * Set the foreground color of a GC using an unallocated color. The
1312  * pixel value for the color will be determined using GdkRGB. If the
1313  * colormap for the GC has not previously been initialized for GdkRGB,
1314  * then for pseudo-color colormaps (colormaps with a small modifiable
1315  * number of colors), a colorcube will be allocated in the colormap.
1316  *
1317  * Calling this function for a GC without a colormap is an error.
1318  *
1319  * Deprecated: 2.22: Use gdk_cairo_set_source_color() instead.
1320  **/
1321 void
gdk_gc_set_rgb_fg_color(GdkGC * gc,const GdkColor * color)1322 gdk_gc_set_rgb_fg_color (GdkGC          *gc,
1323 			 const GdkColor *color)
1324 {
1325   GdkColormap *cmap;
1326   GdkColor tmp_color;
1327 
1328   g_return_if_fail (GDK_IS_GC (gc));
1329   g_return_if_fail (color != NULL);
1330 
1331   cmap = gdk_gc_get_colormap_warn (gc);
1332   if (!cmap)
1333     return;
1334 
1335   tmp_color = *color;
1336   gdk_rgb_find_color (cmap, &tmp_color);
1337   gdk_gc_set_foreground (gc, &tmp_color);
1338 }
1339 
1340 /**
1341  * gdk_gc_set_rgb_bg_color:
1342  * @gc: a #GdkGC
1343  * @color: an unallocated #GdkColor.
1344  *
1345  * Set the background color of a GC using an unallocated color. The
1346  * pixel value for the color will be determined using GdkRGB. If the
1347  * colormap for the GC has not previously been initialized for GdkRGB,
1348  * then for pseudo-color colormaps (colormaps with a small modifiable
1349  * number of colors), a colorcube will be allocated in the colormap.
1350  *
1351  * Calling this function for a GC without a colormap is an error.
1352  *
1353  * Deprecated: 2.22: Use gdk_cairo_set_source_color() instead.
1354  **/
1355 void
gdk_gc_set_rgb_bg_color(GdkGC * gc,const GdkColor * color)1356 gdk_gc_set_rgb_bg_color (GdkGC          *gc,
1357 			 const GdkColor *color)
1358 {
1359   GdkColormap *cmap;
1360   GdkColor tmp_color;
1361 
1362   g_return_if_fail (GDK_IS_GC (gc));
1363   g_return_if_fail (color != NULL);
1364 
1365   cmap = gdk_gc_get_colormap_warn (gc);
1366   if (!cmap)
1367     return;
1368 
1369   tmp_color = *color;
1370   gdk_rgb_find_color (cmap, &tmp_color);
1371   gdk_gc_set_background (gc, &tmp_color);
1372 }
1373 
1374 static cairo_surface_t *
make_stipple_tile_surface(cairo_t * cr,GdkBitmap * stipple,GdkColor * foreground,GdkColor * background)1375 make_stipple_tile_surface (cairo_t   *cr,
1376 			   GdkBitmap *stipple,
1377 			   GdkColor  *foreground,
1378 			   GdkColor  *background)
1379 {
1380   cairo_t *tmp_cr;
1381   cairo_surface_t *surface;
1382   cairo_surface_t *alpha_surface;
1383   gint width, height;
1384 
1385   gdk_drawable_get_size (stipple,
1386 			 &width, &height);
1387 
1388   alpha_surface = _gdk_drawable_ref_cairo_surface (stipple);
1389 
1390   surface = cairo_surface_create_similar (cairo_get_target (cr),
1391 					  CAIRO_CONTENT_COLOR_ALPHA,
1392 					  width, height);
1393 
1394   tmp_cr = cairo_create (surface);
1395 
1396   cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SOURCE);
1397 
1398   if (background)
1399       gdk_cairo_set_source_color (tmp_cr, background);
1400   else
1401       cairo_set_source_rgba (tmp_cr, 0, 0, 0 ,0);
1402 
1403   cairo_paint (tmp_cr);
1404 
1405   cairo_set_operator (tmp_cr, CAIRO_OPERATOR_OVER);
1406 
1407   gdk_cairo_set_source_color (tmp_cr, foreground);
1408   cairo_mask_surface (tmp_cr, alpha_surface, 0, 0);
1409 
1410   cairo_destroy (tmp_cr);
1411   cairo_surface_destroy (alpha_surface);
1412 
1413   return surface;
1414 }
1415 
1416 static void
gc_get_foreground(GdkGC * gc,GdkColor * color)1417 gc_get_foreground (GdkGC    *gc,
1418 		   GdkColor *color)
1419 {
1420   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
1421 
1422   color->pixel = priv->bg_pixel;
1423 
1424   if (gc->colormap)
1425     gdk_colormap_query_color (gc->colormap, priv->fg_pixel, color);
1426   else
1427     g_warning ("No colormap in gc_get_foreground");
1428 }
1429 
1430 static void
gc_get_background(GdkGC * gc,GdkColor * color)1431 gc_get_background (GdkGC    *gc,
1432 		   GdkColor *color)
1433 {
1434   GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc);
1435 
1436   color->pixel = priv->bg_pixel;
1437 
1438   if (gc->colormap)
1439     gdk_colormap_query_color (gc->colormap, priv->bg_pixel, color);
1440   else
1441     g_warning ("No colormap in gc_get_background");
1442 }
1443 
1444 /**
1445  * _gdk_gc_update_context:
1446  * @gc: a #GdkGC
1447  * @cr: a #cairo_t
1448  * @override_foreground: a foreground color to use to override the
1449  *   foreground color of the GC
1450  * @override_stipple: a stipple pattern to use to override the
1451  *   stipple from the GC. If this is present and the fill mode
1452  *   of the GC isn't %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED
1453  *   the fill mode will be forced to %GDK_STIPPLED
1454  * @gc_changed: pass %FALSE if the @gc has not changed since the
1455  *     last call to this function
1456  * @target_drawable: The drawable you're drawing in. If passed in
1457  *     this is used for client side window clip emulation.
1458  *
1459  * Set the attributes of a cairo context to match those of a #GdkGC
1460  * as far as possible. Some aspects of a #GdkGC, such as clip masks
1461  * and functions other than %GDK_COPY are not currently handled.
1462  **/
1463 void
_gdk_gc_update_context(GdkGC * gc,cairo_t * cr,const GdkColor * override_foreground,GdkBitmap * override_stipple,gboolean gc_changed,GdkDrawable * target_drawable)1464 _gdk_gc_update_context (GdkGC          *gc,
1465                         cairo_t        *cr,
1466                         const GdkColor *override_foreground,
1467                         GdkBitmap      *override_stipple,
1468                         gboolean        gc_changed,
1469 			GdkDrawable    *target_drawable)
1470 {
1471   GdkGCPrivate *priv;
1472   GdkFill fill;
1473   GdkColor foreground;
1474   GdkColor background;
1475   cairo_surface_t *tile_surface = NULL;
1476   GdkBitmap *stipple = NULL;
1477 
1478   g_return_if_fail (GDK_IS_GC (gc));
1479   g_return_if_fail (cr != NULL);
1480   g_return_if_fail (override_stipple == NULL || GDK_IS_PIXMAP (override_stipple));
1481 
1482   priv = GDK_GC_GET_PRIVATE (gc);
1483 
1484   _gdk_gc_remove_drawable_clip (gc);
1485 
1486   fill = priv->fill;
1487   if (override_stipple && fill != GDK_OPAQUE_STIPPLED)
1488     fill = GDK_STIPPLED;
1489 
1490   if (fill != GDK_TILED)
1491     {
1492       if (override_foreground)
1493 	foreground = *override_foreground;
1494       else
1495 	gc_get_foreground (gc, &foreground);
1496     }
1497 
1498   if (fill == GDK_OPAQUE_STIPPLED)
1499     gc_get_background (gc, &background);
1500 
1501 
1502   switch (fill)
1503     {
1504     case GDK_SOLID:
1505       break;
1506     case GDK_TILED:
1507       if (!priv->tile)
1508 	fill = GDK_SOLID;
1509       break;
1510     case GDK_STIPPLED:
1511     case GDK_OPAQUE_STIPPLED:
1512       if (override_stipple)
1513 	stipple = override_stipple;
1514       else
1515 	stipple = priv->stipple;
1516 
1517       if (!stipple)
1518 	fill = GDK_SOLID;
1519       break;
1520     }
1521 
1522   switch (fill)
1523     {
1524     case GDK_SOLID:
1525       gdk_cairo_set_source_color (cr, &foreground);
1526       break;
1527     case GDK_TILED:
1528       tile_surface = _gdk_drawable_ref_cairo_surface (priv->tile);
1529       break;
1530     case GDK_STIPPLED:
1531       tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, NULL);
1532       break;
1533     case GDK_OPAQUE_STIPPLED:
1534       tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, &background);
1535       break;
1536     }
1537 
1538   /* Tiles, stipples, and clip regions are all specified in device space,
1539    * not user space. For the clip region, we can simply change the matrix,
1540    * clip, then clip back, but for the source pattern, we need to
1541    * compute the right matrix.
1542    *
1543    * What we want is:
1544    *
1545    *     CTM_inverse * Pattern_matrix = Translate(- ts_x, - ts_y)
1546    *
1547    * (So that ts_x, ts_y in device space is taken to 0,0 in pattern
1548    * space). So, pattern_matrix = CTM * Translate(- ts_x, - tx_y);
1549    */
1550 
1551   if (tile_surface)
1552     {
1553       cairo_pattern_t *pattern = cairo_pattern_create_for_surface (tile_surface);
1554       cairo_matrix_t user_to_device;
1555       cairo_matrix_t user_to_pattern;
1556       cairo_matrix_t device_to_pattern;
1557 
1558       cairo_get_matrix (cr, &user_to_device);
1559       cairo_matrix_init_translate (&device_to_pattern,
1560 				   - gc->ts_x_origin, - gc->ts_y_origin);
1561       cairo_matrix_multiply (&user_to_pattern,
1562 			     &user_to_device, &device_to_pattern);
1563 
1564       cairo_pattern_set_matrix (pattern, &user_to_pattern);
1565       cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
1566       cairo_set_source (cr, pattern);
1567 
1568       cairo_surface_destroy (tile_surface);
1569       cairo_pattern_destroy (pattern);
1570     }
1571 
1572   if (!gc_changed)
1573     return;
1574 
1575   cairo_reset_clip (cr);
1576   /* The reset above resets the window clip rect, so we want to re-set that */
1577   if (target_drawable && GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip)
1578     GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip (target_drawable, cr);
1579 
1580   if (priv->clip_region)
1581     {
1582       cairo_save (cr);
1583 
1584       cairo_identity_matrix (cr);
1585       cairo_translate (cr, gc->clip_x_origin, gc->clip_y_origin);
1586 
1587       cairo_new_path (cr);
1588       gdk_cairo_region (cr, priv->clip_region);
1589 
1590       cairo_restore (cr);
1591 
1592       cairo_clip (cr);
1593     }
1594 
1595 }
1596 
1597 
1598 #define __GDK_GC_C__
1599 #include "gdkaliasdef.c"
1600