]> Pileus Git - ~andy/gtk/blob - gtk/gtktexttag.c
Call gtk_widget_size_request() on reparented child, if one. Otherwise,
[~andy/gtk] / gtk / gtktexttag.c
1 /* gtktexttag.c - text tag object
2  * 
3  * Copyright (c) 1992-1994 The Regents of the University of California.
4  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
5  * Copyright (c) 2000      Red Hat, Inc.
6  * Tk -> Gtk port by Havoc Pennington <hp@redhat.com>
7  *
8  * This software is copyrighted by the Regents of the University of
9  * California, Sun Microsystems, Inc., and other parties.  The
10  * following terms apply to all files associated with the software
11  * unless explicitly disclaimed in individual files.
12  * 
13  * The authors hereby grant permission to use, copy, modify,
14  * distribute, and license this software and its documentation for any
15  * purpose, provided that existing copyright notices are retained in
16  * all copies and that this notice is included verbatim in any
17  * distributions. No written agreement, license, or royalty fee is
18  * required for any of the authorized uses.  Modifications to this
19  * software may be copyrighted by their authors and need not follow
20  * the licensing terms described here, provided that the new terms are
21  * clearly indicated on the first page of each file where they apply.
22  * 
23  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
24  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
25  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
26  * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
27  * OF THE POSSIBILITY OF SUCH DAMAGE.
28  * 
29  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
30  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
32  * NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
33  * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
34  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
35  *
36  * GOVERNMENT USE: If you are acquiring this software on behalf of the
37  * U.S. government, the Government shall have only "Restricted Rights"
38  * in the software and related documentation as defined in the Federal
39  * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
40  * are acquiring the software on behalf of the Department of Defense,
41  * the software shall be classified as "Commercial Computer Software"
42  * and the Government shall have only "Restricted Rights" as defined
43  * in Clause 252.227-7013 (c) (1) of DFARs.  Notwithstanding the
44  * foregoing, the authors grant the U.S. Government and others acting
45  * in its behalf permission to use and distribute the software in
46  * accordance with the terms specified in this license.
47  * 
48  */
49
50 #include "gtkmain.h"
51 #include "gtktexttag.h"
52 #include "gtktexttypes.h"
53 #include "gtktexttagtable.h"
54 #include "gtksignal.h"
55
56 #include <stdlib.h>
57
58 enum {
59   EVENT,
60   LAST_SIGNAL
61 };
62
63 enum {
64   ARG_0,
65   /* Construct args */
66   ARG_NAME,
67
68   /* Style args */
69   ARG_BACKGROUND,
70   ARG_FOREGROUND,
71   ARG_BACKGROUND_GDK,
72   ARG_FOREGROUND_GDK,
73   ARG_BACKGROUND_STIPPLE,
74   ARG_FOREGROUND_STIPPLE,
75   ARG_FONT,
76   ARG_FONT_DESC,
77   ARG_PIXELS_ABOVE_LINES,
78   ARG_PIXELS_BELOW_LINES,
79   ARG_PIXELS_INSIDE_WRAP,
80   ARG_EDITABLE,
81   ARG_WRAP_MODE,
82   ARG_JUSTIFY,
83   ARG_DIRECTION,
84   ARG_LEFT_MARGIN,
85   ARG_LEFT_WRAPPED_LINE_MARGIN,
86   ARG_OVERSTRIKE,
87   ARG_RIGHT_MARGIN,
88   ARG_UNDERLINE,
89   ARG_OFFSET,
90   ARG_BG_FULL_HEIGHT,
91   ARG_LANGUAGE,
92   
93   /* Whether-a-style-arg-is-set args */
94   ARG_BACKGROUND_SET,
95   ARG_FOREGROUND_SET,
96   ARG_BACKGROUND_GDK_SET,
97   ARG_FOREGROUND_GDK_SET,
98   ARG_BACKGROUND_STIPPLE_SET,
99   ARG_FOREGROUND_STIPPLE_SET,
100   ARG_FONT_SET,
101   ARG_PIXELS_ABOVE_LINES_SET,
102   ARG_PIXELS_BELOW_LINES_SET,
103   ARG_PIXELS_INSIDE_WRAP_SET,
104   ARG_EDITABLE_SET,
105   ARG_WRAP_MODE_SET,
106   ARG_JUSTIFY_SET,
107   ARG_LEFT_MARGIN_SET,
108   ARG_LEFT_WRAPPED_LINE_MARGIN_SET,
109   ARG_OVERSTRIKE_SET,
110   ARG_RIGHT_MARGIN_SET,
111   ARG_UNDERLINE_SET,
112   ARG_OFFSET_SET,
113   ARG_BG_FULL_HEIGHT_SET,
114   ARG_LANGUAGE_SET,
115   
116   LAST_ARG
117 };
118
119 static void gtk_text_tag_init       (GtkTextTag      *tkxt_tag);
120 static void gtk_text_tag_class_init (GtkTextTagClass *klass);
121 static void gtk_text_tag_destroy    (GtkObject       *object);
122 static void gtk_text_tag_finalize   (GObject         *object);
123 static void gtk_text_tag_set_arg    (GtkObject       *object,
124                                      GtkArg          *arg,
125                                      guint            arg_id);
126 static void gtk_text_tag_get_arg    (GtkObject       *object,
127                                      GtkArg          *arg,
128                                      guint            arg_id);
129
130 static GtkObjectClass *parent_class = NULL;
131 static guint signals[LAST_SIGNAL] = { 0 };
132
133 GtkType
134 gtk_text_tag_get_type (void)
135 {
136   static GtkType our_type = 0;
137
138   if (our_type == 0)
139     {
140       static const GtkTypeInfo our_info =
141       {
142         "GtkTextTag",
143         sizeof (GtkTextTag),
144         sizeof (GtkTextTagClass),
145         (GtkClassInitFunc) gtk_text_tag_class_init,
146         (GtkObjectInitFunc) gtk_text_tag_init,
147         /* reserved_1 */ NULL,
148         /* reserved_2 */ NULL,
149         (GtkClassInitFunc) NULL
150       };
151
152     our_type = gtk_type_unique (GTK_TYPE_OBJECT, &our_info);
153   }
154
155   return our_type;
156 }
157
158 static void
159 gtk_text_tag_class_init (GtkTextTagClass *klass)
160 {
161   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
162   GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
163
164   parent_class = gtk_type_class (GTK_TYPE_OBJECT);
165
166   /* Construct */
167   gtk_object_add_arg_type ("GtkTextTag::name", GTK_TYPE_STRING,
168                            GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY,
169                            ARG_NAME);
170
171   /* Style args */
172   gtk_object_add_arg_type ("GtkTextTag::background", GTK_TYPE_STRING,
173                            GTK_ARG_WRITABLE, ARG_BACKGROUND);
174   gtk_object_add_arg_type ("GtkTextTag::foreground", GTK_TYPE_STRING,
175                            GTK_ARG_WRITABLE, ARG_FOREGROUND);
176   gtk_object_add_arg_type ("GtkTextTag::background_gdk", GTK_TYPE_GDK_COLOR,
177                            GTK_ARG_READWRITE, ARG_BACKGROUND_GDK);
178   gtk_object_add_arg_type ("GtkTextTag::foreground_gdk", GTK_TYPE_GDK_COLOR,
179                            GTK_ARG_READWRITE, ARG_FOREGROUND_GDK);
180   gtk_object_add_arg_type ("GtkTextTag::background_stipple",
181                            GDK_TYPE_PIXMAP,
182                            GTK_ARG_READWRITE, ARG_BACKGROUND_STIPPLE);
183   gtk_object_add_arg_type ("GtkTextTag::foreground_stipple",
184                            GDK_TYPE_PIXMAP,
185                            GTK_ARG_READWRITE, ARG_FOREGROUND_STIPPLE);
186   gtk_object_add_arg_type ("GtkTextTag::font", GTK_TYPE_STRING,
187                            GTK_ARG_READWRITE, ARG_FONT);
188   gtk_object_add_arg_type ("GtkTextTag::font_desc", GTK_TYPE_BOXED,
189                            GTK_ARG_READWRITE, ARG_FONT_DESC);
190   gtk_object_add_arg_type ("GtkTextTag::pixels_above_lines", GTK_TYPE_INT,
191                            GTK_ARG_READWRITE, ARG_PIXELS_ABOVE_LINES);
192   gtk_object_add_arg_type ("GtkTextTag::pixels_below_lines", GTK_TYPE_INT,
193                            GTK_ARG_READWRITE, ARG_PIXELS_BELOW_LINES);
194   gtk_object_add_arg_type ("GtkTextTag::pixels_inside_wrap", GTK_TYPE_INT,
195                            GTK_ARG_READWRITE, ARG_PIXELS_INSIDE_WRAP);
196   gtk_object_add_arg_type ("GtkTextTag::editable", GTK_TYPE_BOOL,
197                            GTK_ARG_READWRITE, ARG_EDITABLE);
198   gtk_object_add_arg_type ("GtkTextTag::wrap_mode", GTK_TYPE_ENUM,
199                            GTK_ARG_READWRITE, ARG_WRAP_MODE);
200   gtk_object_add_arg_type ("GtkTextTag::justify", GTK_TYPE_ENUM,
201                            GTK_ARG_READWRITE, ARG_JUSTIFY);
202   gtk_object_add_arg_type ("GtkTextTag::direction", GTK_TYPE_ENUM,
203                            GTK_ARG_READWRITE, ARG_DIRECTION);
204   gtk_object_add_arg_type ("GtkTextTag::left_margin", GTK_TYPE_INT,
205                            GTK_ARG_READWRITE, ARG_LEFT_MARGIN);
206   gtk_object_add_arg_type ("GtkTextTag::left_wrapped_line_margin", GTK_TYPE_INT,
207                            GTK_ARG_READWRITE, ARG_LEFT_WRAPPED_LINE_MARGIN);
208   gtk_object_add_arg_type ("GtkTextTag::overstrike", GTK_TYPE_BOOL,
209                            GTK_ARG_READWRITE, ARG_OVERSTRIKE);
210   gtk_object_add_arg_type ("GtkTextTag::right_margin", GTK_TYPE_INT,
211                            GTK_ARG_READWRITE, ARG_RIGHT_MARGIN);
212   gtk_object_add_arg_type ("GtkTextTag::pixels_above_lines", GTK_TYPE_INT,
213                            GTK_ARG_READWRITE, ARG_PIXELS_ABOVE_LINES);
214   gtk_object_add_arg_type ("GtkTextTag::pixels_below_lines", GTK_TYPE_INT,
215                            GTK_ARG_READWRITE, ARG_PIXELS_BELOW_LINES);
216   gtk_object_add_arg_type ("GtkTextTag::pixels_inside_wrap", GTK_TYPE_INT,
217                            GTK_ARG_READWRITE, ARG_PIXELS_INSIDE_WRAP);
218   gtk_object_add_arg_type ("GtkTextTag::underline", GTK_TYPE_ENUM,
219                            GTK_ARG_READWRITE, ARG_UNDERLINE);
220   gtk_object_add_arg_type ("GtkTextTag::wrap_mode", GTK_TYPE_ENUM,
221                            GTK_ARG_READWRITE, ARG_WRAP_MODE);
222   gtk_object_add_arg_type ("GtkTextTag::offset", GTK_TYPE_INT,
223                            GTK_ARG_READWRITE, ARG_OFFSET);
224   gtk_object_add_arg_type ("GtkTextTag::background_full_height", GTK_TYPE_BOOL,
225                            GTK_ARG_READWRITE, ARG_BG_FULL_HEIGHT);
226   gtk_object_add_arg_type ("GtkTextTag::language", GTK_TYPE_STRING,
227                            GTK_ARG_READWRITE, ARG_LANGUAGE);
228   
229   /* Style args are set or not */
230   gtk_object_add_arg_type ("GtkTextTag::background_set", GTK_TYPE_BOOL,
231                            GTK_ARG_READWRITE, ARG_BACKGROUND_SET);
232   gtk_object_add_arg_type ("GtkTextTag::foreground_set", GTK_TYPE_BOOL,
233                            GTK_ARG_READWRITE, ARG_FOREGROUND_SET);
234   gtk_object_add_arg_type ("GtkTextTag::background_gdk_set", GTK_TYPE_BOOL,
235                            GTK_ARG_READWRITE, ARG_BACKGROUND_GDK_SET);
236   gtk_object_add_arg_type ("GtkTextTag::foreground_gdk_set", GTK_TYPE_BOOL,
237                            GTK_ARG_READWRITE, ARG_FOREGROUND_GDK_SET);
238   gtk_object_add_arg_type ("GtkTextTag::background_stipple_set", GTK_TYPE_BOOL,
239                            GTK_ARG_READWRITE, ARG_BACKGROUND_STIPPLE_SET);
240   gtk_object_add_arg_type ("GtkTextTag::foreground_stipple_set", GTK_TYPE_BOOL,
241                            GTK_ARG_READWRITE, ARG_FOREGROUND_STIPPLE_SET);
242   gtk_object_add_arg_type ("GtkTextTag::font_set", GTK_TYPE_BOOL,
243                            GTK_ARG_READWRITE, ARG_FONT_SET);
244   gtk_object_add_arg_type ("GtkTextTag::pixels_above_lines_set", GTK_TYPE_BOOL,
245                            GTK_ARG_READWRITE, ARG_PIXELS_ABOVE_LINES_SET);
246   gtk_object_add_arg_type ("GtkTextTag::pixels_below_lines_set", GTK_TYPE_BOOL,
247                            GTK_ARG_READWRITE, ARG_PIXELS_BELOW_LINES_SET);
248   gtk_object_add_arg_type ("GtkTextTag::pixels_inside_wrap_set", GTK_TYPE_BOOL,
249                            GTK_ARG_READWRITE, ARG_PIXELS_INSIDE_WRAP_SET);
250   gtk_object_add_arg_type ("GtkTextTag::editable_set", GTK_TYPE_BOOL,
251                            GTK_ARG_READWRITE, ARG_EDITABLE_SET);
252   gtk_object_add_arg_type ("GtkTextTag::wrap_mode_set", GTK_TYPE_BOOL,
253                            GTK_ARG_READWRITE, ARG_WRAP_MODE_SET);
254   gtk_object_add_arg_type ("GtkTextTag::justify_set", GTK_TYPE_BOOL,
255                            GTK_ARG_READWRITE, ARG_JUSTIFY_SET);
256   gtk_object_add_arg_type ("GtkTextTag::left_margin_set", GTK_TYPE_BOOL,
257                            GTK_ARG_READWRITE, ARG_LEFT_MARGIN_SET);
258   gtk_object_add_arg_type ("GtkTextTag::left_wrapped_line_margin_set", GTK_TYPE_BOOL,
259                            GTK_ARG_READWRITE, ARG_LEFT_WRAPPED_LINE_MARGIN_SET);
260   gtk_object_add_arg_type ("GtkTextTag::overstrike_set", GTK_TYPE_BOOL,
261                            GTK_ARG_READWRITE, ARG_OVERSTRIKE_SET);
262   gtk_object_add_arg_type ("GtkTextTag::right_margin_set", GTK_TYPE_BOOL,
263                            GTK_ARG_READWRITE, ARG_RIGHT_MARGIN_SET);
264   gtk_object_add_arg_type ("GtkTextTag::pixels_above_lines_set", GTK_TYPE_BOOL,
265                            GTK_ARG_READWRITE, ARG_PIXELS_ABOVE_LINES_SET);
266   gtk_object_add_arg_type ("GtkTextTag::pixels_below_lines_set", GTK_TYPE_BOOL,
267                            GTK_ARG_READWRITE, ARG_PIXELS_BELOW_LINES_SET);
268   gtk_object_add_arg_type ("GtkTextTag::pixels_inside_wrap_set", GTK_TYPE_BOOL,
269                            GTK_ARG_READWRITE, ARG_PIXELS_INSIDE_WRAP_SET);
270   gtk_object_add_arg_type ("GtkTextTag::underline_set", GTK_TYPE_ENUM,
271                            GTK_ARG_READWRITE, ARG_UNDERLINE_SET);
272   gtk_object_add_arg_type ("GtkTextTag::wrap_mode_set", GTK_TYPE_BOOL,
273                            GTK_ARG_READWRITE, ARG_WRAP_MODE_SET);
274   gtk_object_add_arg_type ("GtkTextTag::offset_set", GTK_TYPE_BOOL,
275                            GTK_ARG_READWRITE, ARG_OFFSET_SET);  
276   gtk_object_add_arg_type ("GtkTextTag::background_full_height_set", GTK_TYPE_BOOL,
277                            GTK_ARG_READWRITE, ARG_BG_FULL_HEIGHT_SET);
278   gtk_object_add_arg_type ("GtkTextTag::language_set", GTK_TYPE_BOOL,
279                            GTK_ARG_READWRITE, ARG_LANGUAGE_SET);
280   
281   signals[EVENT] =
282     gtk_signal_new ("event",
283                     GTK_RUN_LAST,
284                     GTK_CLASS_TYPE (object_class),
285                     GTK_SIGNAL_OFFSET (GtkTextTagClass, event),
286                     gtk_marshal_INT__OBJECT_BOXED_POINTER,
287                     GTK_TYPE_INT,
288                     3,
289                     GTK_TYPE_OBJECT,
290                     GTK_TYPE_GDK_EVENT,
291                     GTK_TYPE_POINTER);
292
293   gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
294
295   object_class->set_arg = gtk_text_tag_set_arg;
296   object_class->get_arg = gtk_text_tag_get_arg;
297
298   object_class->destroy = gtk_text_tag_destroy;
299   gobject_class->finalize = gtk_text_tag_finalize;
300 }
301
302 void
303 gtk_text_tag_init (GtkTextTag *tkxt_tag)
304 {
305   /* 0 is basically a fine way to initialize everything in the
306      entire struct */
307   
308 }
309
310 GtkTextTag*
311 gtk_text_tag_new (const gchar *name)
312 {
313   GtkTextTag *tag;
314
315   tag = GTK_TEXT_TAG (gtk_type_new (gtk_text_tag_get_type ()));
316
317   tag->name = g_strdup(name);
318
319   tag->values = gtk_text_style_values_new();
320   
321   return tag;
322 }
323
324 static void
325 gtk_text_tag_destroy (GtkObject *object)
326 {
327   GtkTextTag *tkxt_tag;
328
329   tkxt_tag = GTK_TEXT_TAG (object);
330
331   g_assert(!tkxt_tag->values->realized);
332   
333   if (tkxt_tag->table)
334     gtk_text_tag_table_remove(tkxt_tag->table, tkxt_tag->name);
335
336   g_assert(tkxt_tag->table == NULL);
337   
338   gtk_text_style_values_unref(tkxt_tag->values);
339   tkxt_tag->values = NULL;
340   
341   (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);
342 }
343
344 static void
345 gtk_text_tag_finalize (GObject *object)
346 {
347   GtkTextTag *tkxt_tag;
348
349   tkxt_tag = GTK_TEXT_TAG (object);
350
351   g_free(tkxt_tag->name);
352   tkxt_tag->name = NULL;
353
354   (* G_OBJECT_CLASS(parent_class)->finalize) (object);
355 }
356
357 static void
358 set_bg_color(GtkTextTag *tag, GdkColor *color)
359 {
360   if (color)
361     {
362       tag->bg_color_set = TRUE;
363       tag->values->appearance.bg_color = *color;
364     }
365   else
366     {
367       tag->bg_color_set = FALSE;
368     }
369 }
370
371 static void
372 set_fg_color(GtkTextTag *tag, GdkColor *color)
373 {
374   if (color)
375     {
376       tag->fg_color_set = TRUE;
377       tag->values->appearance.fg_color = *color;
378     }
379   else
380     {
381       tag->fg_color_set = FALSE;
382     }
383 }
384
385 static void
386 gtk_text_tag_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
387 {
388   GtkTextTag *tkxt_tag;
389   gboolean size_changed = FALSE;
390   
391   tkxt_tag = GTK_TEXT_TAG (object);
392
393   g_return_if_fail(!tkxt_tag->values->realized);
394   
395   switch (arg_id)
396     {
397     case ARG_NAME:
398       g_return_if_fail(tkxt_tag->name == NULL);
399       tkxt_tag->name = g_strdup(GTK_VALUE_STRING(*arg));
400       break;
401
402     case ARG_BACKGROUND:
403       {
404         GdkColor color;
405
406         if (gdk_color_parse(GTK_VALUE_STRING(*arg), &color))
407           set_bg_color(tkxt_tag, &color);
408         else
409           g_warning("Don't know color `%s'", GTK_VALUE_STRING(*arg));
410       }
411       break;
412
413     case ARG_FOREGROUND:
414       {
415         GdkColor color;
416
417         if (gdk_color_parse(GTK_VALUE_STRING(*arg), &color))
418           set_fg_color(tkxt_tag, &color);
419         else
420           g_warning("Don't know color `%s'", GTK_VALUE_STRING(*arg));
421       }
422       break;
423       
424     case ARG_BACKGROUND_GDK:
425       {
426         GdkColor *color = GTK_VALUE_POINTER(*arg);
427         set_bg_color(tkxt_tag, color);
428       }
429       break;
430
431     case ARG_FOREGROUND_GDK:
432       {
433         GdkColor *color = GTK_VALUE_POINTER(*arg);
434         set_fg_color(tkxt_tag, color);
435       }
436       break;
437
438     case ARG_BACKGROUND_STIPPLE:
439       {
440         GdkBitmap *bitmap = GTK_VALUE_POINTER(*arg);
441
442         tkxt_tag->bg_stipple_set = TRUE;
443         
444         if (tkxt_tag->values->appearance.bg_stipple != bitmap)
445           {
446             if (bitmap != NULL)
447               gdk_bitmap_ref(bitmap);
448             
449             if (tkxt_tag->values->appearance.bg_stipple)
450               gdk_bitmap_unref(tkxt_tag->values->appearance.bg_stipple);
451             
452             tkxt_tag->values->appearance.bg_stipple = bitmap;
453           }
454       }
455       break;
456
457     case ARG_FOREGROUND_STIPPLE:
458       {
459         GdkBitmap *bitmap = GTK_VALUE_POINTER(*arg);
460
461         tkxt_tag->fg_stipple_set = TRUE;
462         
463         if (tkxt_tag->values->appearance.fg_stipple != bitmap)
464           {
465             if (bitmap != NULL)
466               gdk_bitmap_ref(bitmap);
467             
468             if (tkxt_tag->values->appearance.fg_stipple)
469               gdk_bitmap_unref(tkxt_tag->values->appearance.fg_stipple);
470             
471             tkxt_tag->values->appearance.fg_stipple = bitmap;
472           }
473       }
474       break;
475
476     case ARG_FONT:
477       {
478         PangoFontDescription *font_desc = NULL;
479         const gchar *name;
480
481         name = GTK_VALUE_STRING(*arg);        
482
483         if (name)
484           font_desc = pango_font_description_from_string (name);
485
486         if (tkxt_tag->values->font_desc)
487           pango_font_description_free (tkxt_tag->values->font_desc);
488         
489         tkxt_tag->font_set = (font_desc != NULL);
490         tkxt_tag->values->font_desc = font_desc;
491
492         size_changed = TRUE;
493       }
494       break;
495
496     case ARG_FONT_DESC:
497       {
498         PangoFontDescription *font_desc;
499
500         font_desc = GTK_VALUE_BOXED(*arg);        
501
502         if (tkxt_tag->values->font_desc)
503           pango_font_description_free (tkxt_tag->values->font_desc);
504
505         if (font_desc)
506           tkxt_tag->values->font_desc = pango_font_description_copy (font_desc);
507         else
508           tkxt_tag->values->font_desc = NULL;
509         
510         tkxt_tag->font_set = (font_desc != NULL);
511
512         size_changed = TRUE;
513       }
514       break;
515
516     case ARG_PIXELS_ABOVE_LINES:
517       tkxt_tag->pixels_above_lines_set = TRUE;
518       tkxt_tag->values->pixels_above_lines = GTK_VALUE_INT(*arg);
519       size_changed = TRUE;
520       break;
521
522     case ARG_PIXELS_BELOW_LINES:
523       tkxt_tag->pixels_below_lines_set = TRUE;
524       tkxt_tag->values->pixels_below_lines = GTK_VALUE_INT(*arg);
525       size_changed = TRUE;
526       break;
527
528     case ARG_PIXELS_INSIDE_WRAP:
529       tkxt_tag->pixels_inside_wrap_set = TRUE;
530       tkxt_tag->values->pixels_inside_wrap = GTK_VALUE_INT(*arg);
531       size_changed = TRUE;
532       break;
533
534     case ARG_EDITABLE:
535       tkxt_tag->editable_set = TRUE;
536       tkxt_tag->values->editable = GTK_VALUE_BOOL(*arg);
537       break;
538
539     case ARG_WRAP_MODE:
540       tkxt_tag->wrap_mode_set = TRUE;
541       tkxt_tag->values->wrap_mode = GTK_VALUE_ENUM(*arg);
542       size_changed = TRUE;
543       break;
544
545     case ARG_JUSTIFY:
546       tkxt_tag->justify_set = TRUE;
547       tkxt_tag->values->justify = GTK_VALUE_ENUM(*arg);
548       size_changed = TRUE;
549       break;
550
551     case ARG_DIRECTION:
552       tkxt_tag->values->direction = GTK_VALUE_ENUM(*arg);
553       break;
554
555     case ARG_LEFT_MARGIN:
556       tkxt_tag->left_margin_set = TRUE;
557       tkxt_tag->values->left_margin = GTK_VALUE_INT(*arg);
558       size_changed = TRUE;
559       break;
560
561     case ARG_LEFT_WRAPPED_LINE_MARGIN:
562       tkxt_tag->left_wrapped_line_margin_set = TRUE;
563       tkxt_tag->values->left_wrapped_line_margin = GTK_VALUE_INT(*arg);
564       size_changed = TRUE;
565       break;
566
567     case ARG_OVERSTRIKE:
568       tkxt_tag->overstrike_set = TRUE;
569       tkxt_tag->values->appearance.overstrike = GTK_VALUE_BOOL(*arg);
570       break;
571       
572     case ARG_RIGHT_MARGIN:
573       tkxt_tag->right_margin_set = TRUE;
574       tkxt_tag->values->right_margin = GTK_VALUE_INT(*arg);
575       size_changed = TRUE;
576       break;
577       
578     case ARG_UNDERLINE:
579       tkxt_tag->underline_set = TRUE;
580       tkxt_tag->values->appearance.underline = GTK_VALUE_ENUM(*arg);
581       break;
582       
583     case ARG_OFFSET:
584       tkxt_tag->offset_set = TRUE;
585       tkxt_tag->values->offset = GTK_VALUE_INT(*arg);
586       size_changed = TRUE;
587       break;
588
589     case ARG_BG_FULL_HEIGHT:
590       tkxt_tag->bg_full_height_set = TRUE;
591       tkxt_tag->values->bg_full_height = GTK_VALUE_BOOL(*arg);
592       break;
593
594     case ARG_LANGUAGE:
595       tkxt_tag->language_set = TRUE;
596       tkxt_tag->values->language = g_strdup (GTK_VALUE_STRING(*arg));
597       break;
598       
599       /* Whether the value should be used... */
600       
601     case ARG_BACKGROUND_SET:
602     case ARG_BACKGROUND_GDK_SET:
603       tkxt_tag->bg_color_set = GTK_VALUE_BOOL(*arg);
604       break;
605
606     case ARG_FOREGROUND_SET:
607     case ARG_FOREGROUND_GDK_SET:
608       tkxt_tag->fg_color_set = GTK_VALUE_BOOL(*arg);
609       break;
610
611     case ARG_BACKGROUND_STIPPLE_SET:
612       tkxt_tag->bg_stipple_set = GTK_VALUE_BOOL(*arg);
613       break;
614
615     case ARG_FOREGROUND_STIPPLE_SET:
616       tkxt_tag->fg_stipple_set = GTK_VALUE_BOOL(*arg);
617       break;
618
619     case ARG_FONT_SET:
620       tkxt_tag->font_set = GTK_VALUE_BOOL(*arg);
621       size_changed = TRUE;
622       break;
623
624     case ARG_PIXELS_ABOVE_LINES_SET:
625       tkxt_tag->pixels_above_lines_set = GTK_VALUE_BOOL(*arg);
626       size_changed = TRUE;
627       break;
628
629     case ARG_PIXELS_BELOW_LINES_SET:
630       tkxt_tag->pixels_below_lines_set = GTK_VALUE_BOOL(*arg);
631       size_changed = TRUE;
632       break;
633
634     case ARG_PIXELS_INSIDE_WRAP_SET:
635       tkxt_tag->pixels_inside_wrap_set = GTK_VALUE_BOOL(*arg);
636       size_changed = TRUE;
637       break;
638
639     case ARG_EDITABLE_SET:
640       tkxt_tag->editable_set = GTK_VALUE_BOOL(*arg);
641       break;
642
643     case ARG_WRAP_MODE_SET:
644       tkxt_tag->wrap_mode_set = GTK_VALUE_BOOL(*arg);
645       size_changed = TRUE;
646       break;
647
648     case ARG_JUSTIFY_SET:
649       tkxt_tag->justify_set = GTK_VALUE_BOOL(*arg);
650       size_changed = TRUE;
651       break;
652
653     case ARG_LEFT_MARGIN_SET:
654       tkxt_tag->left_margin_set = GTK_VALUE_BOOL(*arg);
655       size_changed = TRUE;
656       break;
657
658     case ARG_LEFT_WRAPPED_LINE_MARGIN_SET:
659       tkxt_tag->left_wrapped_line_margin_set = GTK_VALUE_BOOL(*arg);
660       size_changed = TRUE;
661       break;
662
663     case ARG_OVERSTRIKE_SET:
664       tkxt_tag->overstrike_set = GTK_VALUE_BOOL(*arg);
665       break;
666
667     case ARG_RIGHT_MARGIN_SET:
668       tkxt_tag->right_margin_set = GTK_VALUE_BOOL(*arg);
669       size_changed = TRUE;
670       break;
671
672     case ARG_UNDERLINE_SET:
673       tkxt_tag->underline_set = GTK_VALUE_BOOL(*arg);
674       break;
675
676     case ARG_OFFSET_SET:
677       tkxt_tag->offset_set = GTK_VALUE_BOOL(*arg);
678       size_changed = TRUE;
679       break;
680
681     case ARG_BG_FULL_HEIGHT_SET:
682       tkxt_tag->bg_full_height_set = GTK_VALUE_BOOL(*arg);
683       break;
684
685     case ARG_LANGUAGE_SET:
686       tkxt_tag->language_set = GTK_VALUE_BOOL(*arg);
687       size_changed = TRUE;
688       break;
689       
690     default:
691       g_assert_not_reached();
692       break;
693     }
694   
695   /* FIXME I would like to do this after all set_arg in a single
696      gtk_object_set() have been called. But an idle function
697      won't work; we need to emit when the tag is changed, not
698      when we get around to the event loop. So blah, we eat some
699      inefficiency. */
700   
701   /* This is also somewhat weird since we emit another object's
702      signal here, but the two objects are already tightly bound. */
703   
704   if (tkxt_tag->table)
705     gtk_signal_emit_by_name(GTK_OBJECT(tkxt_tag->table),
706                             "tag_changed",
707                             tkxt_tag, size_changed);
708 }
709
710 static void
711 get_color_arg (GtkArg *arg, GdkColor *orig)
712 {
713   GdkColor *color;
714   
715   color = g_new (GdkColor, 1);
716   *color = *orig;
717   GTK_VALUE_BOXED (*arg) = color;
718 }
719
720 static void
721 gtk_text_tag_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
722 {
723   GtkTextTag *tag;
724
725   tag = GTK_TEXT_TAG (object);
726
727   switch (arg_id)
728     {
729     case ARG_NAME:
730       GTK_VALUE_STRING(*arg) = g_strdup(tag->name);
731       break;
732       
733     case ARG_BACKGROUND_GDK:
734       get_color_arg(arg, &tag->values->appearance.bg_color);
735       break;
736
737     case ARG_FOREGROUND_GDK:
738       get_color_arg(arg, &tag->values->appearance.fg_color);
739       break;
740
741     case ARG_BACKGROUND_STIPPLE:
742       GTK_VALUE_BOXED(*arg) = tag->values->appearance.bg_stipple;
743       break;
744
745     case ARG_FOREGROUND_STIPPLE:
746       GTK_VALUE_BOXED(*arg) = tag->values->appearance.fg_stipple;
747       break;
748
749     case ARG_FONT:
750       if (tag->values->font_desc)
751         GTK_VALUE_STRING(*arg) = pango_font_description_to_string (tag->values->font_desc);
752       else
753         GTK_VALUE_STRING(*arg) = NULL;
754       break;
755
756     case ARG_FONT_DESC:
757       if (tag->values->font_desc)
758         GTK_VALUE_BOXED(*arg) = pango_font_description_copy (tag->values->font_desc);
759       else
760         GTK_VALUE_BOXED(*arg) = NULL;
761       break;
762
763     case ARG_PIXELS_ABOVE_LINES:
764       GTK_VALUE_INT(*arg) = tag->values->pixels_above_lines;
765       break;
766
767     case ARG_PIXELS_BELOW_LINES:
768       GTK_VALUE_INT(*arg) = tag->values->pixels_below_lines;
769       break;
770
771     case ARG_PIXELS_INSIDE_WRAP:
772       GTK_VALUE_INT(*arg) = tag->values->pixels_inside_wrap;
773       break;
774
775     case ARG_EDITABLE:
776       GTK_VALUE_BOOL(*arg) = tag->values->editable;
777       break;      
778
779     case ARG_WRAP_MODE:
780       GTK_VALUE_ENUM(*arg) = tag->values->wrap_mode;
781       break;
782
783     case ARG_JUSTIFY:
784       GTK_VALUE_ENUM(*arg) = tag->values->justify;
785       break;
786
787     case ARG_LEFT_MARGIN:
788       GTK_VALUE_INT(*arg) = tag->values->left_margin;
789       break;
790
791     case ARG_LEFT_WRAPPED_LINE_MARGIN:
792       GTK_VALUE_INT(*arg) = tag->values->left_wrapped_line_margin;
793       break;
794
795     case ARG_OVERSTRIKE:
796       GTK_VALUE_BOOL(*arg) = tag->values->appearance.overstrike;
797       break;
798       
799     case ARG_RIGHT_MARGIN:
800       GTK_VALUE_INT(*arg) = tag->values->right_margin;
801       break;
802       
803     case ARG_UNDERLINE:
804       GTK_VALUE_ENUM(*arg) = tag->values->appearance.underline;
805       break;
806
807     case ARG_OFFSET:
808       GTK_VALUE_INT(*arg) = tag->values->offset;
809       break;
810
811     case ARG_BG_FULL_HEIGHT:
812       GTK_VALUE_BOOL(*arg) = tag->values->bg_full_height;
813       break;
814
815     case ARG_LANGUAGE:
816       GTK_VALUE_STRING(*arg) = g_strdup (tag->values->language);
817       break;
818       
819     case ARG_BACKGROUND_SET:
820     case ARG_BACKGROUND_GDK_SET:
821       GTK_VALUE_BOOL(*arg) = tag->bg_color_set;
822       break;
823
824     case ARG_FOREGROUND_SET:
825     case ARG_FOREGROUND_GDK_SET:
826       GTK_VALUE_BOOL(*arg) = tag->fg_color_set;
827       break;
828
829     case ARG_BACKGROUND_STIPPLE_SET:
830       GTK_VALUE_BOOL(*arg) = tag->bg_stipple_set;
831       break;
832
833     case ARG_FOREGROUND_STIPPLE_SET:
834       GTK_VALUE_BOOL(*arg) = tag->fg_stipple_set;
835       break;
836
837     case ARG_FONT_SET:
838       GTK_VALUE_BOOL(*arg) = tag->font_set;
839       break;
840
841     case ARG_PIXELS_ABOVE_LINES_SET:
842       GTK_VALUE_BOOL(*arg) = tag->pixels_above_lines_set;
843       break;
844
845     case ARG_PIXELS_BELOW_LINES_SET:
846       GTK_VALUE_BOOL(*arg) = tag->pixels_below_lines_set;
847       break;
848
849     case ARG_PIXELS_INSIDE_WRAP_SET:
850       GTK_VALUE_BOOL(*arg) = tag->pixels_inside_wrap_set;
851       break;
852
853     case ARG_EDITABLE_SET:
854       GTK_VALUE_BOOL(*arg) = tag->editable_set;
855       break;
856
857     case ARG_WRAP_MODE_SET:
858       GTK_VALUE_BOOL(*arg) = tag->wrap_mode_set;
859       break;
860
861     case ARG_JUSTIFY_SET:
862       GTK_VALUE_BOOL(*arg) = tag->justify_set;
863       break;
864
865     case ARG_LEFT_MARGIN_SET:
866       GTK_VALUE_BOOL(*arg) = tag->left_margin_set;
867       break;
868
869     case ARG_LEFT_WRAPPED_LINE_MARGIN_SET:
870       GTK_VALUE_BOOL(*arg) = tag->left_wrapped_line_margin_set;
871       break;
872
873     case ARG_OVERSTRIKE_SET:
874       GTK_VALUE_BOOL(*arg) = tag->overstrike_set;
875       break;
876
877     case ARG_RIGHT_MARGIN_SET:
878       GTK_VALUE_BOOL(*arg) = tag->right_margin_set;
879       break;
880
881     case ARG_UNDERLINE_SET:
882       GTK_VALUE_BOOL(*arg) = tag->underline_set;
883       break;
884
885     case ARG_OFFSET_SET:
886       GTK_VALUE_BOOL(*arg) = tag->offset_set;
887       break;
888
889     case ARG_BG_FULL_HEIGHT_SET:
890       GTK_VALUE_BOOL(*arg) = tag->bg_full_height_set;
891       break;
892
893     case ARG_LANGUAGE_SET:
894       GTK_VALUE_BOOL(*arg) = tag->language_set;
895       break;
896       
897     case ARG_BACKGROUND:
898     case ARG_FOREGROUND:
899     default:
900       arg->type = GTK_TYPE_INVALID;
901       break;
902     }
903   /* FIXME */
904   arg->type = GTK_TYPE_INVALID;
905 }
906
907 /*
908  * Tag operations
909  */
910
911 typedef struct {
912   gint high;
913   gint low;
914   gint delta;
915 } DeltaData;
916
917 static void
918 delta_priority_foreach(gpointer key, gpointer value, gpointer user_data)
919 {
920   GtkTextTag *tag;
921   DeltaData *dd = user_data;
922   
923   tag = GTK_TEXT_TAG(value);
924
925   if (tag->priority >= dd->low && tag->priority <= dd->high)
926     tag->priority += dd->delta;
927 }
928
929 void
930 gtk_text_tag_set_priority(GtkTextTag *tag,
931                            gint priority)
932 {
933     DeltaData dd;
934     
935     g_return_if_fail(GTK_IS_TEXT_TAG(tag));
936     g_return_if_fail(tag->table != NULL);
937     g_return_if_fail(priority >= 0);
938     g_return_if_fail(priority < gtk_text_tag_table_size(tag->table));
939
940     if (priority == tag->priority)
941       return;
942
943     if (priority < tag->priority) {
944       dd.low = priority;
945       dd.high = tag->priority - 1;
946       dd.delta = 1;
947     } else {
948       dd.low = tag->priority + 1;
949       dd.high = priority;
950       dd.delta = -1;
951     }
952
953     gtk_text_tag_table_foreach(tag->table, delta_priority_foreach,
954                                 &dd);
955     
956     tag->priority = priority;
957 }
958
959 gint
960 gtk_text_tag_event(GtkTextTag *tag,
961                     GtkObject *event_object,
962                     GdkEvent *event,
963                     const GtkTextIter *iter)
964 {
965   gint retval = FALSE;
966
967   g_return_val_if_fail(GTK_IS_TEXT_TAG(tag), FALSE);
968   g_return_val_if_fail(GTK_IS_OBJECT(event_object), FALSE);
969   g_return_val_if_fail(event != NULL, FALSE);
970   
971   gtk_signal_emit(GTK_OBJECT(tag),
972                   signals[EVENT],
973                   event_object,
974                   event,
975                   iter,
976                   &retval);
977
978   return retval;
979 }
980
981 static int
982 tag_sort_func(gconstpointer first, gconstpointer second)
983 {
984     GtkTextTag *tag1, *tag2;
985
986     tag1 = * (GtkTextTag **) first;
987     tag2 = * (GtkTextTag **) second;
988     return tag1->priority - tag2->priority;
989 }
990
991 void
992 gtk_text_tag_array_sort(GtkTextTag** tag_array_p,
993                          guint len)
994 {
995   int i, j, prio;
996   GtkTextTag **tag;
997   GtkTextTag **maxPtrPtr, *tmp;
998
999   g_return_if_fail(tag_array_p != NULL);
1000   g_return_if_fail(len > 0);
1001   
1002   if (len < 2) {
1003     return;
1004   }
1005   if (len < 20) {
1006     GtkTextTag **iter = tag_array_p;
1007
1008     for (i = len-1; i > 0; i--, iter++) {
1009       maxPtrPtr = tag = iter;
1010       prio = tag[0]->priority;
1011       for (j = i, tag++; j > 0; j--, tag++) {
1012         if (tag[0]->priority < prio) {
1013           prio = tag[0]->priority;
1014           maxPtrPtr = tag;
1015         }
1016       }
1017       tmp = *maxPtrPtr;
1018       *maxPtrPtr = *iter;
1019       *iter = tmp;
1020     }
1021   } else {
1022     qsort((void *) tag_array_p, (unsigned) len, sizeof (GtkTextTag *),
1023           tag_sort_func);
1024   }
1025
1026 #if 0
1027   {
1028     printf("Sorted tag array: \n");
1029     i = 0;
1030     while (i < len)
1031       {
1032         GtkTextTag *t = tag_array_p[i];
1033         printf("  %s priority %d\n", t->name, t->priority);
1034         
1035         ++i;
1036       }
1037   }
1038 #endif
1039 }
1040
1041 /*
1042  * StyleValues
1043  */
1044
1045 GtkTextStyleValues*
1046 gtk_text_style_values_new(void)
1047 {
1048   GtkTextStyleValues *values;
1049
1050   values = g_new0(GtkTextStyleValues, 1);
1051
1052   /* 0 is a valid value for most of the struct */
1053
1054   values->refcount = 1;
1055
1056   values->language = gtk_get_default_language ();
1057   
1058   return values;
1059 }
1060
1061 void
1062 gtk_text_style_values_copy(GtkTextStyleValues *src,
1063                            GtkTextStyleValues *dest)
1064 {
1065   guint orig_refcount;
1066
1067   g_return_if_fail(!dest->realized);
1068
1069   if (src == dest)
1070     return;
1071   
1072   /* Add refs */
1073   
1074   if (src->appearance.bg_stipple)
1075     gdk_bitmap_ref(src->appearance.bg_stipple);
1076
1077   if (src->appearance.fg_stipple)
1078     gdk_bitmap_ref(src->appearance.fg_stipple);
1079
1080   if (src->tab_array)
1081     gtk_text_view_tab_array_ref(src->tab_array);
1082
1083   /* Remove refs */
1084   
1085   if (dest->appearance.bg_stipple)
1086     gdk_bitmap_unref(dest->appearance.bg_stipple);
1087
1088   if (dest->appearance.fg_stipple)
1089     gdk_bitmap_unref(dest->appearance.fg_stipple);
1090
1091   if (dest->tab_array)
1092     gtk_text_view_tab_array_unref(dest->tab_array);
1093
1094   /* Copy */
1095   orig_refcount = dest->refcount;
1096   
1097   *dest = *src;
1098
1099   dest->font_desc = pango_font_description_copy (src->font_desc);
1100   dest->language = g_strdup (src->language);
1101   
1102   dest->refcount = orig_refcount;
1103   dest->realized = FALSE;
1104 }
1105
1106 void
1107 gtk_text_style_values_ref(GtkTextStyleValues *values)
1108 {
1109   g_return_if_fail(values != NULL);
1110
1111   values->refcount += 1;
1112 }
1113
1114 void
1115 gtk_text_style_values_unref(GtkTextStyleValues *values)
1116 {
1117   g_return_if_fail(values != NULL);
1118   g_return_if_fail(values->refcount > 0);
1119
1120   values->refcount -= 1;
1121
1122   if (values->refcount == 0)
1123     {
1124       g_assert(!values->realized);
1125       
1126       if (values->appearance.bg_stipple)
1127         gdk_bitmap_unref(values->appearance.bg_stipple);
1128       
1129       if (values->font_desc)
1130         pango_font_description_free (values->font_desc);
1131       
1132       if (values->appearance.fg_stipple)
1133         gdk_bitmap_unref(values->appearance.fg_stipple);
1134
1135       if (values->tab_array)
1136         gtk_text_view_tab_array_unref(values->tab_array);
1137
1138       if (values->language)
1139         g_free (values->language);
1140       
1141       g_free(values);
1142     }
1143 }
1144
1145 void
1146 gtk_text_style_values_realize(GtkTextStyleValues *values,
1147                               GdkColormap *cmap,
1148                               GdkVisual *visual)
1149 {
1150   g_return_if_fail(values != NULL);
1151   g_return_if_fail(values->refcount > 0);
1152   g_return_if_fail(!values->realized);
1153   
1154   /* It is wrong to use this colormap, FIXME */
1155   gdk_colormap_alloc_color(cmap,
1156                            &values->appearance.fg_color,
1157                            FALSE, TRUE);
1158
1159   gdk_colormap_alloc_color(cmap,
1160                            &values->appearance.bg_color,
1161                            FALSE, TRUE);
1162
1163   values->realized = TRUE;
1164 }
1165
1166 void
1167 gtk_text_style_values_unrealize(GtkTextStyleValues *values,
1168                                 GdkColormap *cmap,
1169                                 GdkVisual *visual)
1170 {
1171   g_return_if_fail(values != NULL);
1172   g_return_if_fail(values->refcount > 0);
1173   g_return_if_fail(values->realized);
1174   
1175   gdk_colormap_free_colors(cmap,
1176                            &values->appearance.fg_color, 1);
1177   
1178   
1179   gdk_colormap_free_colors(cmap,
1180                            &values->appearance.bg_color, 1);
1181
1182   values->appearance.fg_color.pixel = 0;
1183   values->appearance.bg_color.pixel = 0;
1184
1185   values->realized = FALSE;
1186 }
1187
1188 void
1189 gtk_text_style_values_fill_from_tags(GtkTextStyleValues *dest,
1190                                      GtkTextTag**        tags,
1191                                      guint               n_tags)
1192 {
1193   guint n = 0;
1194
1195   g_return_if_fail(!dest->realized);  
1196   
1197   while (n < n_tags)
1198     {
1199       GtkTextTag *tag = tags[n];
1200       GtkTextStyleValues *vals = tag->values;
1201
1202       if (n > 0)
1203         g_assert(tags[n]->priority > tags[n-1]->priority);
1204       
1205       if (tag->bg_color_set)
1206         {
1207           dest->appearance.bg_color = vals->appearance.bg_color;
1208           
1209           dest->appearance.draw_bg = TRUE;
1210         }
1211       
1212       if (tag->border_width_set)
1213         dest->border_width = vals->border_width;
1214
1215       if (tag->relief_set)
1216         dest->relief = vals->relief;
1217
1218       if (tag->bg_stipple_set)
1219         {
1220           gdk_bitmap_ref(vals->appearance.bg_stipple);
1221           if (dest->appearance.bg_stipple)
1222             gdk_bitmap_unref(dest->appearance.bg_stipple);
1223           dest->appearance.bg_stipple = vals->appearance.bg_stipple;
1224
1225           dest->appearance.draw_bg = TRUE;
1226         }
1227
1228       if (tag->fg_color_set)
1229         dest->appearance.fg_color = vals->appearance.fg_color;
1230          
1231       if (tag->font_set)
1232         {
1233           if (dest->font_desc)
1234             pango_font_description_free (dest->font_desc);
1235           dest->font_desc = pango_font_description_copy (vals->font_desc);
1236         }
1237
1238       if (tag->fg_stipple_set)
1239         {
1240           gdk_bitmap_ref(vals->appearance.fg_stipple);
1241           if (dest->appearance.fg_stipple)
1242             gdk_bitmap_unref(dest->appearance.fg_stipple);
1243           dest->appearance.fg_stipple = vals->appearance.fg_stipple;
1244         }
1245
1246       if (tag->justify_set)
1247         dest->justify = vals->justify;
1248
1249       if (vals->direction != GTK_TEXT_DIR_NONE)
1250         dest->direction = vals->direction;
1251       
1252       if (tag->left_margin_set)
1253         dest->left_margin = vals->left_margin;
1254
1255       if (tag->left_wrapped_line_margin_set)
1256         dest->left_wrapped_line_margin = vals->left_wrapped_line_margin;
1257
1258       if (tag->offset_set)
1259         dest->offset = vals->offset;
1260
1261       if (tag->right_margin_set)
1262         dest->right_margin = vals->right_margin;
1263
1264       if (tag->pixels_above_lines_set)
1265         dest->pixels_above_lines = vals->pixels_above_lines;
1266
1267       if (tag->pixels_below_lines_set)
1268         dest->pixels_below_lines = vals->pixels_below_lines;
1269
1270       if (tag->pixels_inside_wrap_set)
1271         dest->pixels_inside_wrap = vals->pixels_inside_wrap;
1272
1273       if (tag->tab_array_set)
1274         {
1275           gtk_text_view_tab_array_ref(vals->tab_array);
1276           if (dest->tab_array)
1277             gtk_text_view_tab_array_unref(dest->tab_array);
1278           dest->tab_array = vals->tab_array;
1279         }
1280
1281       if (tag->wrap_mode_set)
1282         dest->wrap_mode = vals->wrap_mode;
1283
1284       if (tag->underline_set)
1285         dest->appearance.underline = vals->appearance.underline;
1286
1287       if (tag->overstrike_set)
1288         dest->appearance.overstrike = vals->appearance.overstrike;
1289
1290       if (tag->elide_set)
1291         dest->elide = vals->elide;
1292
1293       if (tag->editable_set)
1294         dest->editable = vals->editable;
1295
1296       if (tag->bg_full_height_set)
1297         dest->bg_full_height = vals->bg_full_height;
1298
1299       if (tag->language_set)
1300         {
1301           g_free (dest->language);
1302           dest->language = g_strdup (vals->language);
1303         }
1304       
1305       ++n;
1306     }
1307 }