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