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