]> Pileus Git - ~andy/gtk/blob - gdk/gdkgc.c
doc fix proposed by tvv@sparc.spb.su (Vitaly Tishkov), #73567.
[~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 <string.h>
28
29 #include "gdkgc.h"
30 #include "gdkrgb.h"
31 #include "gdkprivate.h"
32
33 static void gdk_gc_class_init (GObjectClass *class);
34 static void gdk_gc_finalize   (GObject      *object);
35
36 static GObjectClass *parent_class;
37
38 GType
39 gdk_gc_get_type (void)
40 {
41   static GType object_type = 0;
42
43   if (!object_type)
44     {
45       static const GTypeInfo object_info =
46       {
47         sizeof (GdkGCClass),
48         (GBaseInitFunc) NULL,
49         (GBaseFinalizeFunc) NULL,
50         (GClassInitFunc) gdk_gc_class_init,
51         NULL,           /* class_finalize */
52         NULL,           /* class_data */
53         sizeof (GdkGC),
54         0,              /* n_preallocs */
55         (GInstanceInitFunc) NULL,
56       };
57       
58       object_type = g_type_register_static (G_TYPE_OBJECT,
59                                             "GdkGC",
60                                             &object_info, 0);
61     }
62   
63   return object_type;
64 }
65
66 static void
67 gdk_gc_class_init (GObjectClass *class)
68 {
69   parent_class = g_type_class_peek_parent (class);
70   
71   class->finalize = gdk_gc_finalize;
72 }
73
74 GdkGC*
75 gdk_gc_new (GdkDrawable *drawable)
76 {
77   g_return_val_if_fail (drawable != NULL, NULL);
78
79   return gdk_gc_new_with_values (drawable, NULL, 0);
80 }
81
82 GdkGC*
83 gdk_gc_new_with_values (GdkDrawable     *drawable,
84                         GdkGCValues     *values,
85                         GdkGCValuesMask  values_mask)
86 {
87   GdkGC *gc;
88
89   g_return_val_if_fail (drawable != NULL, NULL);
90
91   gc = GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable,
92                                                      values,
93                                                      values_mask);
94
95   if (gc == NULL) /* This would mean the drawable was destroyed. */
96     return NULL;
97   
98   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
99     gc->clip_x_origin = values->clip_x_origin;
100   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
101     gc->clip_y_origin = values->clip_y_origin;
102   if (values_mask & GDK_GC_TS_X_ORIGIN)
103     gc->ts_x_origin = values->ts_x_origin;
104   if (values_mask & GDK_GC_TS_Y_ORIGIN)
105     gc->ts_y_origin = values->ts_y_origin;
106
107   gc->colormap = gdk_drawable_get_colormap (drawable);
108   if (gc->colormap)
109     g_object_ref (G_OBJECT (gc->colormap));
110   
111   return gc;
112 }
113
114 static void
115 gdk_gc_finalize (GObject *object)
116 {
117   GdkGC *gc = GDK_GC (object);
118   
119   if (gc->colormap)
120     g_object_unref (G_OBJECT (gc->colormap));
121
122   parent_class->finalize (object);
123 }
124
125 /**
126  * gdk_gc_ref:
127  * @gc: a #GdkGC
128  *
129  * Deprecated function; use g_object_ref() instead.
130  *
131  * Return value: the gc.
132  **/
133 GdkGC *
134 gdk_gc_ref (GdkGC *gc)
135 {
136   return (GdkGC *) g_object_ref (G_OBJECT (gc));
137 }
138
139 /**
140  * gdk_gc_unref:
141  * @gc: a #GdkGC
142  *
143  * Deprecated function; use g_object_unref() instead.
144  **/
145 void
146 gdk_gc_unref (GdkGC *gc)
147 {
148   g_object_unref (G_OBJECT (gc));
149 }
150
151 void
152 gdk_gc_get_values (GdkGC       *gc,
153                    GdkGCValues *values)
154 {
155   g_return_if_fail (GDK_IS_GC (gc));
156   g_return_if_fail (values != NULL);
157
158   GDK_GC_GET_CLASS (gc)->get_values (gc, values);
159 }
160
161 /**
162  * gdk_gc_set_values:
163  * @gc: a #GdkGC
164  * @values: struct containing the new values
165  * @values_mask: mask indicating which struct fields are to be used
166  *
167  * Sets attributes of a graphics context in bulk. For each flag set in
168  * @values_mask, the corresponding field will be read from @values and
169  * set as the new value for @gc. If you're only setting a few values
170  * on @gc, calling individual "setter" functions is likely more
171  * convenient.
172  * 
173  **/
174 void
175 gdk_gc_set_values (GdkGC           *gc,
176                    GdkGCValues     *values,
177                    GdkGCValuesMask  values_mask)
178 {
179   g_return_if_fail (GDK_IS_GC (gc));
180   g_return_if_fail (values != NULL);
181
182   if (values_mask & GDK_GC_CLIP_X_ORIGIN)
183     gc->clip_x_origin = values->clip_x_origin;
184   if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
185     gc->clip_y_origin = values->clip_y_origin;
186   if (values_mask & GDK_GC_TS_X_ORIGIN)
187     gc->ts_x_origin = values->ts_x_origin;
188   if (values_mask & GDK_GC_TS_Y_ORIGIN)
189     gc->ts_y_origin = values->ts_y_origin;
190   
191   GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask);
192 }
193
194 void
195 gdk_gc_set_foreground (GdkGC    *gc,
196                        GdkColor *color)
197 {
198   GdkGCValues values;
199
200   g_return_if_fail (GDK_IS_GC (gc));
201   g_return_if_fail (color != NULL);
202
203   values.foreground = *color;
204   gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND);
205 }
206
207 void
208 gdk_gc_set_background (GdkGC    *gc,
209                        GdkColor *color)
210 {
211   GdkGCValues values;
212
213   g_return_if_fail (GDK_IS_GC (gc));
214   g_return_if_fail (color != NULL);
215
216   values.background = *color;
217   gdk_gc_set_values (gc, &values, GDK_GC_BACKGROUND);
218 }
219
220 void
221 gdk_gc_set_font (GdkGC   *gc,
222                  GdkFont *font)
223 {
224   GdkGCValues values;
225
226   g_return_if_fail (GDK_IS_GC (gc));
227   g_return_if_fail (font != NULL);
228
229   values.font = font;
230   gdk_gc_set_values (gc, &values, GDK_GC_FONT);
231 }
232
233 void
234 gdk_gc_set_function (GdkGC       *gc,
235                      GdkFunction  function)
236 {
237   GdkGCValues values;
238
239   g_return_if_fail (GDK_IS_GC (gc));
240
241   values.function = function;
242   gdk_gc_set_values (gc, &values, GDK_GC_FUNCTION);
243 }
244
245 void
246 gdk_gc_set_fill (GdkGC   *gc,
247                  GdkFill  fill)
248 {
249   GdkGCValues values;
250
251   g_return_if_fail (GDK_IS_GC (gc));
252
253   values.fill = fill;
254   gdk_gc_set_values (gc, &values, GDK_GC_FILL);
255 }
256
257 void
258 gdk_gc_set_tile (GdkGC     *gc,
259                  GdkPixmap *tile)
260 {
261   GdkGCValues values;
262
263   g_return_if_fail (GDK_IS_GC (gc));
264
265   values.tile = tile;
266   gdk_gc_set_values (gc, &values, GDK_GC_TILE);
267 }
268
269 void
270 gdk_gc_set_stipple (GdkGC     *gc,
271                     GdkPixmap *stipple)
272 {
273   GdkGCValues values;
274
275   g_return_if_fail (GDK_IS_GC (gc));
276
277   values.stipple = stipple;
278   gdk_gc_set_values (gc, &values, GDK_GC_STIPPLE);
279 }
280
281 void
282 gdk_gc_set_ts_origin (GdkGC *gc,
283                       gint   x,
284                       gint   y)
285 {
286   GdkGCValues values;
287
288   g_return_if_fail (GDK_IS_GC (gc));
289
290   values.ts_x_origin = x;
291   values.ts_y_origin = y;
292   
293   gdk_gc_set_values (gc, &values,
294                      GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
295 }
296
297 void
298 gdk_gc_set_clip_origin (GdkGC *gc,
299                         gint   x,
300                         gint   y)
301 {
302   GdkGCValues values;
303
304   g_return_if_fail (GDK_IS_GC (gc));
305
306   values.clip_x_origin = x;
307   values.clip_y_origin = y;
308   
309   gdk_gc_set_values (gc, &values,
310                      GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
311 }
312
313 void
314 gdk_gc_set_clip_mask (GdkGC     *gc,
315                       GdkBitmap *mask)
316 {
317   GdkGCValues values;
318   
319   g_return_if_fail (GDK_IS_GC (gc));
320   
321   values.clip_mask = mask;
322   gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK);
323 }
324
325
326 void
327 gdk_gc_set_subwindow (GdkGC            *gc,
328                       GdkSubwindowMode  mode)
329 {
330   GdkGCValues values;
331
332   g_return_if_fail (GDK_IS_GC (gc));
333
334   values.subwindow_mode = mode;
335   gdk_gc_set_values (gc, &values, GDK_GC_SUBWINDOW);
336 }
337
338 void
339 gdk_gc_set_exposures (GdkGC     *gc,
340                       gboolean   exposures)
341 {
342   GdkGCValues values;
343
344   g_return_if_fail (GDK_IS_GC (gc));
345
346   values.graphics_exposures = exposures;
347   gdk_gc_set_values (gc, &values, GDK_GC_EXPOSURES);
348 }
349
350 void
351 gdk_gc_set_line_attributes (GdkGC       *gc,
352                             gint         line_width,
353                             GdkLineStyle line_style,
354                             GdkCapStyle  cap_style,
355                             GdkJoinStyle join_style)
356 {
357   GdkGCValues values;
358
359   values.line_width = line_width;
360   values.line_style = line_style;
361   values.cap_style = cap_style;
362   values.join_style = join_style;
363
364   gdk_gc_set_values (gc, &values,
365                      GDK_GC_LINE_WIDTH |
366                      GDK_GC_LINE_STYLE |
367                      GDK_GC_CAP_STYLE |
368                      GDK_GC_JOIN_STYLE);
369 }
370
371 void
372 gdk_gc_set_dashes (GdkGC *gc,
373                    gint   dash_offset,
374                    gint8  dash_list[],
375                    gint   n)
376 {
377   g_return_if_fail (GDK_IS_GC (gc));
378   g_return_if_fail (dash_list != NULL);
379
380   GDK_GC_GET_CLASS (gc)->set_dashes (gc, dash_offset, dash_list, n);
381 }
382
383 /**
384  * gdk_gc_offset:
385  * @gc: a #GdkGC
386  * @x_offset: amount by which to offset the GC in the X direction
387  * @y_offset: amount by which to offset the GC in the Y direction
388  * 
389  * Offset attributes such as the clip and tile-stipple origins
390  * of the GC so that drawing at x - x_offset, y - y_offset with
391  * the offset GC  has the same effect as drawing at x, y with the original
392  * GC.
393  **/
394 void
395 gdk_gc_offset (GdkGC *gc,
396                gint   x_offset,
397                gint   y_offset)
398 {
399   if (x_offset != 0 || y_offset != 0)
400     {
401       GdkGCValues values;
402
403       values.clip_x_origin = gc->clip_x_origin - x_offset;
404       values.clip_y_origin = gc->clip_y_origin - y_offset;
405       values.ts_x_origin = gc->ts_x_origin - x_offset;
406       values.ts_y_origin = gc->ts_y_origin - y_offset;
407       
408       gdk_gc_set_values (gc, &values,
409                          GDK_GC_CLIP_X_ORIGIN |
410                          GDK_GC_CLIP_Y_ORIGIN |
411                          GDK_GC_TS_X_ORIGIN |
412                          GDK_GC_TS_Y_ORIGIN);
413     }
414 }
415
416 /**
417  * gdk_gc_set_colormap:
418  * @gc: a #GdkGC
419  * @colormap: a #GdkColormap
420  * 
421  * Sets the colormap for the GC to the given colormap. The depth
422  * of the colormap's visual must match the depth of the drawable
423  * for which the GC was created.
424  **/
425 void
426 gdk_gc_set_colormap (GdkGC       *gc,
427                      GdkColormap *colormap)
428 {
429   g_return_if_fail (GDK_IS_GC (gc));
430   g_return_if_fail (GDK_IS_COLORMAP (colormap));
431
432   if (gc->colormap != colormap)
433     {
434       if (gc->colormap)
435         g_object_unref (G_OBJECT (gc->colormap));
436
437       gc->colormap = colormap;
438       g_object_ref (G_OBJECT (gc->colormap));
439     }
440     
441 }
442
443 /**
444  * gdk_gc_get_colormap:
445  * @gc: a #GdkGC
446  * 
447  * Retrieves the colormap for a given GC, if it exists.
448  * A GC will have a colormap if the drawable for which it was created
449  * has a colormap, or if a colormap was set explicitely with
450  * gdk_gc_set_colormap.
451  * 
452  * Return value: 
453  **/
454 GdkColormap *
455 gdk_gc_get_colormap (GdkGC *gc)
456 {
457   g_return_val_if_fail (GDK_IS_GC (gc), NULL);
458
459   return gc->colormap;
460 }
461
462 static GdkColormap *
463 gdk_gc_get_colormap_warn (GdkGC *gc)
464 {
465   GdkColormap *colormap = gdk_gc_get_colormap (gc);
466   if (!colormap)
467     {
468       g_warning ("gdk_gc_set_rgb_fg_color() and gdk_gc_set_rgb_bg_color() can\n"
469                  "only be used on GC's with a colormap. A GC will have a colormap\n"
470                  "if it is created for a drawable with a colormap, or if a\n"
471                  "colormap has been set explicitly with gdk_gc_set_colormap.\n");
472       return NULL;
473     }
474
475   return colormap;
476 }
477
478 /**
479  * gdk_gc_set_rgb_fg_color:
480  * @gc: a #GdkGC
481  * @color: an unallocated #GdkColor.
482  * 
483  * Set the foreground color of a GC using an unallocated color. The
484  * pixel value for the color will be determined using GdkRGB. If the
485  * colormap for the GC has not previously been initialized for GdkRGB,
486  * then for pseudo-color colormaps (colormaps with a small modifiable
487  * number of colors), a colorcube will be allocated in the colormap.
488  * 
489  * Calling this function for a GC without a colormap is an error.
490  **/
491 void
492 gdk_gc_set_rgb_fg_color (GdkGC *gc, GdkColor *color)
493 {
494   GdkColormap *cmap;
495   GdkColor tmp_color;
496
497   g_return_if_fail (GDK_IS_GC (gc));
498   g_return_if_fail (color != NULL);
499
500   cmap = gdk_gc_get_colormap_warn (gc);
501   if (!cmap)
502     return;
503
504   tmp_color = *color;
505   gdk_rgb_find_color (cmap, &tmp_color);
506   gdk_gc_set_foreground (gc, &tmp_color);
507 }
508
509 /**
510  * gdk_gc_set_rgb_bg_color:
511  * @gc: a #GdkGC
512  * @color: an unallocated #GdkColor.
513  * 
514  * Set the background color of a GC using an unallocated color. The
515  * pixel value for the color will be determined using GdkRGB. If the
516  * colormap for the GC has not previously been initialized for GdkRGB,
517  * then for pseudo-color colormaps (colormaps with a small modifiable
518  * number of colors), a colorcube will be allocated in the colormap.
519  * 
520  * Calling this function for a GC without a colormap is an error.
521  **/
522 void
523 gdk_gc_set_rgb_bg_color (GdkGC *gc, GdkColor *color)
524 {
525   GdkColormap *cmap;
526   GdkColor tmp_color;
527
528   g_return_if_fail (GDK_IS_GC (gc));
529   g_return_if_fail (color != NULL);
530
531   cmap = gdk_gc_get_colormap_warn (gc);
532   if (!cmap)
533     return;
534
535   tmp_color = *color;
536   gdk_rgb_find_color (cmap, &tmp_color);
537   gdk_gc_set_background (gc, &tmp_color);
538 }