]> Pileus Git - ~andy/gtk/blob - gtk/gtktexttag.c
coalescing property notifies
[~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 #include "gtkintl.h"
57 #include "gtktypebuiltins.h"
58
59 #include <stdlib.h>
60 #include <string.h>
61
62 enum {
63   EVENT,
64   LAST_SIGNAL
65 };
66
67 enum {
68   PROP_0,
69   /* Construct args */
70   PROP_NAME,
71
72   /* Style args */
73   PROP_BACKGROUND,
74   PROP_FOREGROUND,
75   PROP_BACKGROUND_GDK,
76   PROP_FOREGROUND_GDK,
77   PROP_BACKGROUND_STIPPLE,
78   PROP_FOREGROUND_STIPPLE,
79   PROP_FONT,
80   PROP_FONT_DESC,
81   PROP_FAMILY,
82   PROP_STYLE,
83   PROP_VARIANT,
84   PROP_WEIGHT,
85   PROP_STRETCH,
86   PROP_SIZE,
87   PROP_SIZE_POINTS,
88   PROP_SCALE,
89   PROP_PIXELS_ABOVE_LINES,
90   PROP_PIXELS_BELOW_LINES,
91   PROP_PIXELS_INSIDE_WRAP,
92   PROP_EDITABLE,
93   PROP_WRAP_MODE,
94   PROP_JUSTIFICATION,
95   PROP_DIRECTION,
96   PROP_LEFT_MARGIN,
97   PROP_INDENT,
98   PROP_STRIKETHROUGH,
99   PROP_RIGHT_MARGIN,
100   PROP_UNDERLINE,
101   PROP_RISE,
102   PROP_BG_FULL_HEIGHT,
103   PROP_LANGUAGE,
104   PROP_TABS,
105   PROP_INVISIBLE,
106   
107   /* Whether-a-style-arg-is-set args */
108   PROP_BACKGROUND_SET,
109   PROP_FOREGROUND_SET,
110   PROP_BACKGROUND_STIPPLE_SET,
111   PROP_FOREGROUND_STIPPLE_SET,
112   PROP_FAMILY_SET,
113   PROP_STYLE_SET,
114   PROP_VARIANT_SET,
115   PROP_WEIGHT_SET,
116   PROP_STRETCH_SET,
117   PROP_SIZE_SET,
118   PROP_SCALE_SET,
119   PROP_PIXELS_ABOVE_LINES_SET,
120   PROP_PIXELS_BELOW_LINES_SET,
121   PROP_PIXELS_INSIDE_WRAP_SET,
122   PROP_EDITABLE_SET,
123   PROP_WRAP_MODE_SET,
124   PROP_JUSTIFICATION_SET,
125   PROP_LEFT_MARGIN_SET,
126   PROP_INDENT_SET,
127   PROP_STRIKETHROUGH_SET,
128   PROP_RIGHT_MARGIN_SET,
129   PROP_UNDERLINE_SET,
130   PROP_RISE_SET,
131   PROP_BG_FULL_HEIGHT_SET,
132   PROP_LANGUAGE_SET,
133   PROP_TABS_SET,
134   PROP_INVISIBLE_SET,
135
136   LAST_ARG
137 };
138 static void gtk_text_tag_init         (GtkTextTag      *text_tag);
139 static void gtk_text_tag_class_init   (GtkTextTagClass *klass);
140 static void gtk_text_tag_finalize     (GObject         *object);
141 static void gtk_text_tag_set_property (GObject         *object,
142                                        guint            prop_id,
143                                        const GValue    *value,
144                                        GParamSpec      *pspec);
145 static void gtk_text_tag_get_property (GObject         *object,
146                                        guint            prop_id,
147                                        GValue          *value,
148                                        GParamSpec      *pspec);
149
150 static GObjectClass *parent_class = NULL;
151 static guint signals[LAST_SIGNAL] = { 0 };
152
153 GType
154 gtk_text_tag_get_type (void)
155 {
156   static GType our_type = 0;
157
158   if (our_type == 0)
159     {
160       static const GTypeInfo our_info =
161       {
162         sizeof (GtkTextTagClass),
163         (GBaseInitFunc) NULL,
164         (GBaseFinalizeFunc) NULL,
165         (GClassInitFunc) gtk_text_tag_class_init,
166         NULL,           /* class_finalize */
167         NULL,           /* class_data */
168         sizeof (GtkTextTag),
169         0,              /* n_preallocs */
170         (GInstanceInitFunc) gtk_text_tag_init
171       };
172
173       our_type = g_type_register_static (G_TYPE_OBJECT,
174                                          "GtkTextTag",
175                                          &our_info,
176                                          0);
177     }
178
179   return our_type;
180 }
181
182 static void
183 gtk_text_tag_class_init (GtkTextTagClass *klass)
184 {
185   GObjectClass *object_class = G_OBJECT_CLASS (klass);
186
187   parent_class = g_type_class_peek_parent (klass);
188
189   object_class->set_property = gtk_text_tag_set_property;
190   object_class->get_property = gtk_text_tag_get_property;
191   
192   object_class->finalize = gtk_text_tag_finalize;
193
194   /* Construct */
195   g_object_class_install_property (object_class,
196                                    PROP_NAME,
197                                    g_param_spec_string ("name",
198                                                         _("Tag name"),
199                                                         _("Name used to refer to the text tag"),
200                                                         NULL,
201                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
202
203   /* Style args */
204
205   g_object_class_install_property (object_class,
206                                    PROP_BACKGROUND,
207                                    g_param_spec_string ("background",
208                                                         _("Background color name"),
209                                                         _("Background color as a string"),
210                                                         NULL,
211                                                         G_PARAM_WRITABLE));
212
213   g_object_class_install_property (object_class,
214                                    PROP_BACKGROUND_GDK,
215                                    g_param_spec_boxed ("background_gdk",
216                                                        _("Background color"),
217                                                        _("Background color as a GdkColor"),
218                                                        GDK_TYPE_COLOR,
219                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
220
221   g_object_class_install_property (object_class,
222                                    PROP_BG_FULL_HEIGHT,
223                                    g_param_spec_boolean ("background_full_height",
224                                                          _("Background full height"),
225                                                          _("Whether the background color fills the entire line height or only the height of the tagged characters"),
226                                                          FALSE,
227                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
228
229   
230   g_object_class_install_property (object_class,
231                                    PROP_BACKGROUND_STIPPLE,
232                                    g_param_spec_object ("background_stipple",
233                                                         _("Background stipple mask"),
234                                                         _("Bitmap to use as a mask when drawing the text background"),
235                                                         GDK_TYPE_PIXMAP,
236                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));  
237
238
239   g_object_class_install_property (object_class,
240                                    PROP_FOREGROUND,
241                                    g_param_spec_string ("foreground",
242                                                         _("Foreground color name"),
243                                                         _("Foreground color as a string"),
244                                                         NULL,
245                                                         G_PARAM_WRITABLE));
246
247   g_object_class_install_property (object_class,
248                                    PROP_FOREGROUND_GDK,
249                                    g_param_spec_boxed ("foreground_gdk",
250                                                        _("Foreground color"),
251                                                        _("Foreground color as a GdkColor"),
252                                                        GDK_TYPE_COLOR,
253                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
254
255   
256   g_object_class_install_property (object_class,
257                                    PROP_FOREGROUND_STIPPLE,
258                                    g_param_spec_object ("foreground_stipple",
259                                                         _("Foreground stipple mask"),
260                                                         _("Bitmap to use as a mask when drawing the text foreground"),
261                                                         GDK_TYPE_PIXMAP,
262                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));  
263   
264   g_object_class_install_property (object_class,
265                                    PROP_DIRECTION,
266                                    g_param_spec_enum ("direction",
267                                                       _("Text direction"),
268                                                       _("Text direction, e.g. right-to-left or left-to-right"),
269                                                       GTK_TYPE_TEXT_DIRECTION,
270                                                       GTK_TEXT_DIR_LTR,
271                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
272
273   g_object_class_install_property (object_class,
274                                    PROP_EDITABLE,
275                                    g_param_spec_boolean ("editable",
276                                                          _("Editable"),
277                                                          _("Whether the text can be modified by the user"),
278                                                          TRUE,
279                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
280
281   g_object_class_install_property (object_class,
282                                    PROP_FONT,
283                                    g_param_spec_string ("font",
284                                                         _("Font"),
285                                                         _("Font description as a string"),
286                                                         NULL,
287                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
288
289   g_object_class_install_property (object_class,
290                                    PROP_FONT_DESC,
291                                    g_param_spec_boxed ("font_desc",
292                                                        _("Font"),
293                                                        _("Font description as a PangoFontDescription struct"),
294                                                        PANGO_TYPE_FONT_DESCRIPTION,
295                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
296
297   
298   g_object_class_install_property (object_class,
299                                    PROP_FAMILY,
300                                    g_param_spec_string ("family",
301                                                         _("Font family"),
302                                                         _("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"),
303                                                         NULL,
304                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
305
306   g_object_class_install_property (object_class,
307                                    PROP_STYLE,
308                                    g_param_spec_enum ("style",
309                                                       _("Font style"),
310                                                       _("Font style"),
311                                                       PANGO_TYPE_STYLE,
312                                                       PANGO_STYLE_NORMAL,
313                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
314
315   g_object_class_install_property (object_class,
316                                    PROP_VARIANT,
317                                    g_param_spec_enum ("variant",
318                                                      _("Font variant"),
319                                                      _("Font variant"),
320                                                       PANGO_TYPE_VARIANT,
321                                                       PANGO_VARIANT_NORMAL,
322                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
323   
324   g_object_class_install_property (object_class,
325                                    PROP_WEIGHT,
326                                    g_param_spec_int ("weight",
327                                                      _("Font weight"),
328                                                      _("Font weight"),
329                                                      0,
330                                                      G_MAXINT,
331                                                      PANGO_WEIGHT_NORMAL,
332                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
333   
334
335   g_object_class_install_property (object_class,
336                                    PROP_STRETCH,
337                                    g_param_spec_enum ("stretch",
338                                                       _("Font stretch"),
339                                                       _("Font stretch"),
340                                                       PANGO_TYPE_STRETCH,
341                                                       PANGO_STRETCH_NORMAL,
342                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
343   
344   g_object_class_install_property (object_class,
345                                    PROP_SIZE,
346                                    g_param_spec_int ("size",
347                                                      _("Font size"),
348                                                      _("Font size"),
349                                                      0,
350                                                      G_MAXINT,
351                                                      0,
352                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
353
354   g_object_class_install_property (object_class,
355                                    PROP_SCALE,
356                                    g_param_spec_double ("scale",
357                                                         _("Font scale"),
358                                                         _("Font scale"),
359                                                         0.0,
360                                                         G_MAXDOUBLE,
361                                                         1.0,
362                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
363   
364   g_object_class_install_property (object_class,
365                                    PROP_SIZE_POINTS,
366                                    g_param_spec_double ("size_points",
367                                                         _("Font points"),
368                                                         _("Font size in points"),
369                                                         0.0,
370                                                         G_MAXDOUBLE,
371                                                         0.0,
372                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));  
373
374   g_object_class_install_property (object_class,
375                                    PROP_JUSTIFICATION,
376                                    g_param_spec_enum ("justification",
377                                                       _("Justification"),
378                                                       _("Left, right, or center justification"),
379                                                       GTK_TYPE_JUSTIFICATION,
380                                                       GTK_JUSTIFY_LEFT,
381                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
382   
383   g_object_class_install_property (object_class,
384                                    PROP_LANGUAGE,
385                                    g_param_spec_string ("language",
386                                                         _("Language"),
387                                                         _("Language engine code to use for rendering the text"),
388                                                         NULL,
389                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));  
390
391   g_object_class_install_property (object_class,
392                                    PROP_LEFT_MARGIN,
393                                    g_param_spec_int ("left_margin",
394                                                      _("Left margin"),
395                                                      _("Width of the left margin in pixels"),
396                                                      0,
397                                                      G_MAXINT,
398                                                      0,
399                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
400
401   g_object_class_install_property (object_class,
402                                    PROP_RIGHT_MARGIN,
403                                    g_param_spec_int ("right_margin",
404                                                      _("Right margin"),
405                                                      _("Width of the right margin in pixels"),
406                                                      0,
407                                                      G_MAXINT,
408                                                      0,
409                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
410
411   
412   g_object_class_install_property (object_class,
413                                    PROP_INDENT,
414                                    g_param_spec_int ("indent",
415                                                      _("Indent"),
416                                                      _("Amount to indent the paragraph, in pixels"),
417                                                      0,
418                                                      G_MAXINT,
419                                                      0,
420                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
421
422   
423   g_object_class_install_property (object_class,
424                                    PROP_RISE,
425                                    g_param_spec_int ("rise",
426                                                      _("Rise"),
427                                                      _("Offset of text above the baseline (below the baseline if rise is negative)"),
428                                                      -G_MAXINT,
429                                                      G_MAXINT,
430                                                      0,
431                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
432
433   g_object_class_install_property (object_class,
434                                    PROP_PIXELS_ABOVE_LINES,
435                                    g_param_spec_int ("pixels_above_lines",
436                                                      _("Pixels above lines"),
437                                                      _("Pixels of blank space above paragraphs"),
438                                                      0,
439                                                      G_MAXINT,
440                                                      0,
441                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
442   
443   g_object_class_install_property (object_class,
444                                    PROP_PIXELS_BELOW_LINES,
445                                    g_param_spec_int ("pixels_below_lines",
446                                                      _("Pixels below lines"),
447                                                      _("Pixels of blank space below paragraphs"),
448                                                      0,
449                                                      G_MAXINT,
450                                                      0,
451                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
452
453   g_object_class_install_property (object_class,
454                                    PROP_PIXELS_INSIDE_WRAP,
455                                    g_param_spec_int ("pixels_inside_wrap",
456                                                      _("Pixels inside wrap"),
457                                                      _("Pixels of blank space between wrapped lines in a paragraph"),
458                                                      0,
459                                                      G_MAXINT,
460                                                      0,
461                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
462
463   g_object_class_install_property (object_class,
464                                    PROP_STRIKETHROUGH,
465                                    g_param_spec_boolean ("strikethrough",
466                                                          _("Strikethrough"),
467                                                          _("Whether to strike through the text"),
468                                                          FALSE,
469                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
470   
471   g_object_class_install_property (object_class,
472                                    PROP_UNDERLINE,
473                                    g_param_spec_enum ("underline",
474                                                       _("Underline"),
475                                                       _("Style of underline for this text"),
476                                                       PANGO_TYPE_UNDERLINE,
477                                                       PANGO_UNDERLINE_NONE,
478                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
479   
480   g_object_class_install_property (object_class,
481                                    PROP_WRAP_MODE,
482                                    g_param_spec_enum ("wrap_mode",
483                                                      _("Wrap mode"),
484                                                      _("Whether to wrap lines never, at word boundaries, or at character boundaries"),
485                                                       GTK_TYPE_WRAP_MODE,
486                                                       GTK_WRAP_NONE,
487                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
488   
489
490   g_object_class_install_property (object_class,
491                                    PROP_TABS,
492                                    g_param_spec_boxed ("tabs",
493                                                        _("Tabs"),
494                                                        _("Custom tabs for this text"),
495                                                        PANGO_TYPE_TAB_ARRAY,
496                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
497   
498   g_object_class_install_property (object_class,
499                                    PROP_INVISIBLE,
500                                    g_param_spec_boolean ("invisible",
501                                                          _("Invisible"),
502                                                          _("Whether this text is hidden"),
503                                                          FALSE,
504                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
505
506   /* Style props are set or not */
507
508 #define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (object_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE))
509
510   ADD_SET_PROP ("background_set", PROP_BACKGROUND_SET,
511                 _("Background set"),
512                 _("Whether this tag affects the background color"));
513   
514   ADD_SET_PROP ("background_full_height_set", PROP_BG_FULL_HEIGHT_SET,
515                 _("Background full height set"),
516                 _("Whether this tag affects background height"));
517
518   ADD_SET_PROP ("background_stipple_set", PROP_BACKGROUND_STIPPLE_SET,
519                 _("Background stipple set"),
520                 _("Whether this tag affects the background stipple"));  
521
522   ADD_SET_PROP ("foreground_set", PROP_FOREGROUND_SET,
523                 _("Foreground set"),
524                 _("Whether this tag affects the foreground color"));
525
526   ADD_SET_PROP ("foreground_stipple_set", PROP_FOREGROUND_STIPPLE_SET,
527                 _("Foreground stipple set"),
528                 _("Whether this tag affects the foreground stipple"));
529   
530   ADD_SET_PROP ("editable_set", PROP_EDITABLE_SET,
531                 _("Editability set"),
532                 _("Whether this tag affects text editability"));
533
534   ADD_SET_PROP ("family_set", PROP_FAMILY_SET,
535                 _("Font family set"),
536                 _("Whether this tag affects the font family"));  
537
538   ADD_SET_PROP ("style_set", PROP_STYLE_SET,
539                 _("Font style set"),
540                 _("Whether this tag affects the font style"));
541
542   ADD_SET_PROP ("variant_set", PROP_VARIANT_SET,
543                 _("Font variant set"),
544                 _("Whether this tag affects the font variant"));
545
546   ADD_SET_PROP ("weight_set", PROP_WEIGHT_SET,
547                 _("Font weight set"),
548                 _("Whether this tag affects the font weight"));
549
550   ADD_SET_PROP ("stretch_set", PROP_STRETCH_SET,
551                 _("Font stretch set"),
552                 _("Whether this tag affects the font stretch"));
553
554   ADD_SET_PROP ("size_set", PROP_SIZE_SET,
555                 _("Font size set"),
556                 _("Whether this tag affects the font size"));
557
558   ADD_SET_PROP ("scale_set", PROP_SCALE_SET,
559                 _("Font scale set"),
560                 _("Whether this tag scales the font size by a factor"));
561   
562   ADD_SET_PROP ("justification_set", PROP_JUSTIFICATION_SET,
563                 _("Justification set"),
564                 _("Whether this tag affects paragraph justification"));
565   
566   ADD_SET_PROP ("language_set", PROP_LANGUAGE_SET,
567                 _("Language set"),
568                 _("Whether this tag affects the language the text is rendered as"));
569
570   ADD_SET_PROP ("left_margin_set", PROP_LEFT_MARGIN_SET,
571                 _("Left margin set"),
572                 _("Whether this tag affects the left margin"));
573
574   ADD_SET_PROP ("indent_set", PROP_INDENT_SET,
575                 _("Indent set"),
576                 _("Whether this tag affects indentation"));
577
578   ADD_SET_PROP ("rise_set", PROP_RISE_SET,
579                 _("Rise set"),
580                 _("Whether this tag affects the rise"));
581
582   ADD_SET_PROP ("pixels_above_lines_set", PROP_PIXELS_ABOVE_LINES_SET,
583                 _("Pixels above lines set"),
584                 _("Whether this tag affects the number of pixels above lines"));
585
586   ADD_SET_PROP ("pixels_below_lines_set", PROP_PIXELS_BELOW_LINES_SET,
587                 _("Pixels below lines set"),
588                 _("Whether this tag affects the number of pixels above lines"));
589
590   ADD_SET_PROP ("pixels_inside_wrap_set", PROP_PIXELS_INSIDE_WRAP_SET,
591                 _("Pixels inside wrap set"),
592                 _("Whether this tag affects the number of pixels between wrapped lines"));
593
594   ADD_SET_PROP ("strikethrough_set", PROP_STRIKETHROUGH_SET,
595                 _("Strikethrough set"),
596                 _("Whether this tag affects strikethrough"));
597   
598   ADD_SET_PROP ("right_margin_set", PROP_RIGHT_MARGIN_SET,
599                 _("Right margin set"),
600                 _("Whether this tag affects the right margin"));
601
602   ADD_SET_PROP ("underline_set", PROP_UNDERLINE_SET,
603                 _("Underline set"),
604                 _("Whether this tag affects underlining"));
605
606   ADD_SET_PROP ("wrap_mode_set", PROP_WRAP_MODE_SET,
607                 _("Wrap mode set"),
608                 _("Whether this tag affects line wrap mode"));
609
610   ADD_SET_PROP ("tabs_set", PROP_TABS_SET,
611                 _("Tabs set"),
612                 _("Whether this tag affects tabs"));
613
614   ADD_SET_PROP ("invisible_set", PROP_INVISIBLE_SET,
615                 _("Invisible set"),
616                 _("Whether this tag affects text visibility"));
617
618   signals[EVENT] =
619     g_signal_new ("event",
620                   G_OBJECT_CLASS_TYPE (object_class),
621                   G_SIGNAL_RUN_LAST,
622                   GTK_SIGNAL_OFFSET (GtkTextTagClass, event),
623                   _gtk_boolean_handled_accumulator, NULL,
624                   gtk_marshal_BOOLEAN__OBJECT_BOXED_BOXED,
625                   G_TYPE_BOOLEAN,
626                   3,
627                   G_TYPE_OBJECT,
628                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
629                   GTK_TYPE_TEXT_ITER);
630 }
631
632 void
633 gtk_text_tag_init (GtkTextTag *text_tag)
634 {
635   /* 0 is basically a fine way to initialize everything in the
636      entire struct */
637   
638   text_tag->values = gtk_text_attributes_new ();
639 }
640
641 /**
642  * gtk_text_tag_new:
643  * @name: tag name, or %NULL
644  * 
645  * Creates a #GtkTextTag. Configure the tag using object arguments,
646  * i.e. using g_object_set().
647  * 
648  * Return value: a new #GtkTextTag
649  **/
650 GtkTextTag*
651 gtk_text_tag_new (const gchar *name)
652 {
653   GtkTextTag *tag;
654
655   tag = GTK_TEXT_TAG (g_object_new (gtk_text_tag_get_type (),
656                                     "name", name,
657                                     NULL));
658
659   return tag;
660 }
661
662 static void
663 gtk_text_tag_finalize (GObject *object)
664 {
665   GtkTextTag *text_tag;
666
667   text_tag = GTK_TEXT_TAG (object);
668
669   g_assert (!text_tag->values->realized);
670
671   if (text_tag->table)
672     gtk_text_tag_table_remove (text_tag->table, text_tag);
673
674   g_assert (text_tag->table == NULL);
675
676   gtk_text_attributes_unref (text_tag->values);
677   text_tag->values = NULL;
678   
679   g_free (text_tag->name);
680   text_tag->name = NULL;
681
682   (* G_OBJECT_CLASS (parent_class)->finalize) (object);
683 }
684
685 static void
686 set_bg_color (GtkTextTag *tag, GdkColor *color)
687 {
688   if (color)
689     {
690       if (!tag->bg_color_set)
691         {
692           tag->bg_color_set = TRUE;
693           g_object_notify (G_OBJECT (tag), "background_set");
694         }
695       
696       tag->values->appearance.bg_color = *color;
697     }
698   else
699     {
700       if (tag->bg_color_set)
701         {
702           tag->bg_color_set = FALSE;
703           g_object_notify (G_OBJECT (tag), "background_set");
704         }
705     }
706 }
707
708 static void
709 set_fg_color (GtkTextTag *tag, GdkColor *color)
710 {
711   if (color)
712     {
713       if (!tag->fg_color_set)
714         {
715           tag->fg_color_set = TRUE;
716           g_object_notify (G_OBJECT (tag), "foreground_set");
717         }
718       tag->values->appearance.fg_color = *color;
719     }
720   else
721     {
722       if (tag->fg_color_set)
723         {
724           tag->fg_color_set = FALSE;
725           g_object_notify (G_OBJECT (tag), "foreground_set");
726         }
727     }
728 }
729
730 static void
731 set_font_description (GtkTextTag           *text_tag,
732                       PangoFontDescription *font_desc)
733 {
734   if (font_desc != NULL)
735     {
736       /* pango_font_description_from_string() will sometimes return
737        * a NULL family or -1 size, so handle those cases.
738        */
739       
740       if (font_desc->family_name)
741         g_object_set (G_OBJECT (text_tag),
742                       "family", font_desc->family_name,
743                       NULL);
744       
745       if (font_desc->size >= 0)
746         g_object_set (G_OBJECT (text_tag),
747                       "size", font_desc->size,
748                       NULL);
749         
750       g_object_set (G_OBJECT (text_tag),
751                     "style", font_desc->style,
752                     "variant", font_desc->variant,
753                     "weight", font_desc->weight,
754                     "stretch", font_desc->stretch,
755                     NULL);
756     }
757   else
758     {
759       g_object_freeze_notify (G_OBJECT (text_tag));
760       if (text_tag->family_set)
761         {
762           text_tag->family_set = FALSE;
763           g_object_notify (G_OBJECT (text_tag), "family_set");
764         }
765       if (text_tag->style_set)
766         {
767           text_tag->style_set = FALSE;
768           g_object_notify (G_OBJECT (text_tag), "style_set");
769         }
770       if (text_tag->variant_set)
771         {
772           text_tag->variant_set = FALSE;
773           g_object_notify (G_OBJECT (text_tag), "variant_set");
774         }
775       if (text_tag->weight_set)
776         {
777           text_tag->weight_set = FALSE;
778           g_object_notify (G_OBJECT (text_tag), "weight_set");
779         }
780       if (text_tag->stretch_set)
781         {
782           text_tag->stretch_set = FALSE;
783           g_object_notify (G_OBJECT (text_tag), "stretch_set");
784         }
785       if (text_tag->size_set)
786         {
787           text_tag->size_set = FALSE;
788           g_object_notify (G_OBJECT (text_tag), "size_set");
789         }
790       g_object_thaw_notify (G_OBJECT (text_tag));
791     }
792 }
793
794 static void
795 gtk_text_tag_set_property (GObject      *object,
796                            guint         prop_id,
797                            const GValue *value,
798                            GParamSpec   *pspec)
799 {
800   GtkTextTag *text_tag;
801   gboolean size_changed = FALSE;
802
803   text_tag = GTK_TEXT_TAG (object);
804
805   g_return_if_fail (!text_tag->values->realized);
806
807   switch (prop_id)
808     {
809     case PROP_NAME:
810       g_return_if_fail (text_tag->name == NULL);
811       text_tag->name = g_strdup (g_value_get_string (value));
812       break;
813
814     case PROP_BACKGROUND:
815       {
816         GdkColor color;
817
818         if (gdk_color_parse (g_value_get_string (value), &color))
819           set_bg_color (text_tag, &color);
820         else
821           g_warning ("Don't know color `%s'", g_value_get_string (value));
822
823         g_object_notify (G_OBJECT (text_tag), "background_gdk");
824       }
825       break;
826
827     case PROP_FOREGROUND:
828       {
829         GdkColor color;
830
831         if (gdk_color_parse (g_value_get_string (value), &color))
832           set_fg_color (text_tag, &color);
833         else
834           g_warning ("Don't know color `%s'", g_value_get_string (value));
835
836         g_object_notify (G_OBJECT (text_tag), "foreground_gdk");
837       }
838       break;
839
840     case PROP_BACKGROUND_GDK:
841       {
842         GdkColor *color = g_value_get_boxed (value);
843
844         set_bg_color (text_tag, color);
845       }
846       break;
847
848     case PROP_FOREGROUND_GDK:
849       {
850         GdkColor *color = g_value_get_boxed (value);
851
852         set_fg_color (text_tag, color);
853       }
854       break;
855
856     case PROP_BACKGROUND_STIPPLE:
857       {
858         GdkBitmap *bitmap = g_value_get_object (value);
859
860         text_tag->bg_stipple_set = TRUE;
861         g_object_notify (G_OBJECT (text_tag), "background_stipple_set");
862         
863         if (text_tag->values->appearance.bg_stipple != bitmap)
864           {
865             if (bitmap != NULL)
866               gdk_bitmap_ref (bitmap);
867
868             if (text_tag->values->appearance.bg_stipple)
869               gdk_bitmap_unref (text_tag->values->appearance.bg_stipple);
870
871             text_tag->values->appearance.bg_stipple = bitmap;
872           }
873       }
874       break;
875
876     case PROP_FOREGROUND_STIPPLE:
877       {
878         GdkBitmap *bitmap = g_value_get_object (value);
879
880         text_tag->fg_stipple_set = TRUE;
881         g_object_notify (G_OBJECT (text_tag), "foreground_stipple_set");
882
883         if (text_tag->values->appearance.fg_stipple != bitmap)
884           {
885             if (bitmap != NULL)
886               gdk_bitmap_ref (bitmap);
887
888             if (text_tag->values->appearance.fg_stipple)
889               gdk_bitmap_unref (text_tag->values->appearance.fg_stipple);
890
891             text_tag->values->appearance.fg_stipple = bitmap;
892           }
893       }
894       break;
895
896     case PROP_FONT:
897       {
898         PangoFontDescription *font_desc = NULL;
899         const gchar *name;
900
901         name = g_value_get_string (value);
902
903         if (name)
904           font_desc = pango_font_description_from_string (name);
905
906         set_font_description (text_tag, font_desc);
907         
908         if (font_desc)
909           pango_font_description_free (font_desc);
910         
911         size_changed = TRUE;
912       }
913       break;
914
915     case PROP_FONT_DESC:
916       {
917         PangoFontDescription *font_desc;
918
919         font_desc = g_value_get_boxed (value);
920
921         set_font_description (text_tag, font_desc);
922
923         size_changed = TRUE;
924       }
925       break;
926
927     case PROP_FAMILY:
928       if (text_tag->values->font.family_name)
929         g_free (text_tag->values->font.family_name);
930       text_tag->values->font.family_name = g_strdup (g_value_get_string (value));
931       text_tag->family_set = TRUE;
932       g_object_notify (G_OBJECT (text_tag), "family_set");
933       g_object_notify (G_OBJECT (text_tag), "font_desc");
934       g_object_notify (G_OBJECT (text_tag), "font");
935       size_changed = TRUE;
936       break;
937
938     case PROP_STYLE:
939       text_tag->values->font.style = g_value_get_enum (value);
940       text_tag->style_set = TRUE;
941       g_object_notify (G_OBJECT (text_tag), "style_set");
942       g_object_notify (G_OBJECT (text_tag), "font_desc");
943       g_object_notify (G_OBJECT (text_tag), "font");
944       size_changed = TRUE;
945       break;
946
947     case PROP_VARIANT:
948       text_tag->values->font.variant = g_value_get_enum (value);
949       text_tag->variant_set = TRUE;
950       g_object_notify (G_OBJECT (text_tag), "variant_set");
951       g_object_notify (G_OBJECT (text_tag), "font_desc");
952       g_object_notify (G_OBJECT (text_tag), "font");
953       size_changed = TRUE;
954       break;
955
956     case PROP_WEIGHT:
957       text_tag->values->font.weight = g_value_get_int (value);
958       text_tag->weight_set = TRUE;
959       g_object_notify (G_OBJECT (text_tag), "weight_set");
960       g_object_notify (G_OBJECT (text_tag), "font_desc");
961       g_object_notify (G_OBJECT (text_tag), "font");
962       size_changed = TRUE;
963       break;
964
965     case PROP_STRETCH:
966       text_tag->values->font.stretch = g_value_get_enum (value);
967       text_tag->stretch_set = TRUE;
968       g_object_notify (G_OBJECT (text_tag), "stretch_set");
969       g_object_notify (G_OBJECT (text_tag), "font_desc");
970       g_object_notify (G_OBJECT (text_tag), "font");
971       size_changed = TRUE;
972       break;
973
974     case PROP_SIZE:
975       text_tag->values->font.size = g_value_get_int (value);
976       text_tag->size_set = TRUE;
977       g_object_notify (G_OBJECT (text_tag), "size_points");
978       g_object_notify (G_OBJECT (text_tag), "size_set");
979       g_object_notify (G_OBJECT (text_tag), "font_desc");
980       g_object_notify (G_OBJECT (text_tag), "font");
981       size_changed = TRUE;
982       break;
983
984     case PROP_SCALE:
985       text_tag->values->font_scale = g_value_get_double (value);
986       text_tag->scale_set = TRUE;
987       size_changed = TRUE;
988       break;
989       
990     case PROP_SIZE_POINTS:
991       text_tag->values->font.size = g_value_get_double (value) * PANGO_SCALE;
992       text_tag->size_set = TRUE;
993       g_object_notify (G_OBJECT (text_tag), "size");
994       g_object_notify (G_OBJECT (text_tag), "size_set");
995       g_object_notify (G_OBJECT (text_tag), "font_desc");
996       g_object_notify (G_OBJECT (text_tag), "font");
997       size_changed = TRUE;
998       break;
999       
1000     case PROP_PIXELS_ABOVE_LINES:
1001       text_tag->pixels_above_lines_set = TRUE;
1002       text_tag->values->pixels_above_lines = g_value_get_int (value);
1003       g_object_notify (G_OBJECT (text_tag), "pixels_above_lines_set");
1004       size_changed = TRUE;
1005       break;
1006
1007     case PROP_PIXELS_BELOW_LINES:
1008       text_tag->pixels_below_lines_set = TRUE;
1009       text_tag->values->pixels_below_lines = g_value_get_int (value);
1010       g_object_notify (G_OBJECT (text_tag), "pixels_below_lines_set");
1011       size_changed = TRUE;
1012       break;
1013
1014     case PROP_PIXELS_INSIDE_WRAP:
1015       text_tag->pixels_inside_wrap_set = TRUE;
1016       text_tag->values->pixels_inside_wrap = g_value_get_int (value);
1017       g_object_notify (G_OBJECT (text_tag), "pixels_inside_wrap_set");
1018       size_changed = TRUE;
1019       break;
1020
1021     case PROP_EDITABLE:
1022       text_tag->editable_set = TRUE;
1023       text_tag->values->editable = g_value_get_boolean (value);
1024       g_object_notify (G_OBJECT (text_tag), "editable_set");
1025       break;
1026
1027     case PROP_WRAP_MODE:
1028       text_tag->wrap_mode_set = TRUE;
1029       text_tag->values->wrap_mode = g_value_get_enum (value);
1030       g_object_notify (G_OBJECT (text_tag), "wrap_mode_set");
1031       size_changed = TRUE;
1032       break;
1033
1034     case PROP_JUSTIFICATION:
1035       text_tag->justification_set = TRUE;
1036       text_tag->values->justification = g_value_get_enum (value);
1037       g_object_notify (G_OBJECT (text_tag), "justification_set");
1038       size_changed = TRUE;
1039       break;
1040
1041     case PROP_DIRECTION:
1042       text_tag->values->direction = g_value_get_enum (value);
1043       break;
1044
1045     case PROP_LEFT_MARGIN:
1046       text_tag->left_margin_set = TRUE;
1047       text_tag->values->left_margin = g_value_get_int (value);
1048       g_object_notify (G_OBJECT (text_tag), "left_margin_set");
1049       size_changed = TRUE;
1050       break;
1051
1052     case PROP_INDENT:
1053       text_tag->indent_set = TRUE;
1054       text_tag->values->indent = g_value_get_int (value);
1055       g_object_notify (G_OBJECT (text_tag), "indent_set");
1056       size_changed = TRUE;
1057       break;
1058
1059     case PROP_STRIKETHROUGH:
1060       text_tag->strikethrough_set = TRUE;
1061       text_tag->values->appearance.strikethrough = g_value_get_boolean (value);
1062       g_object_notify (G_OBJECT (text_tag), "strikethrough_set");
1063       break;
1064
1065     case PROP_RIGHT_MARGIN:
1066       text_tag->right_margin_set = TRUE;
1067       text_tag->values->right_margin = g_value_get_int (value);
1068       g_object_notify (G_OBJECT (text_tag), "right_margin_set");
1069       size_changed = TRUE;
1070       break;
1071
1072     case PROP_UNDERLINE:
1073       text_tag->underline_set = TRUE;
1074       text_tag->values->appearance.underline = g_value_get_enum (value);
1075       g_object_notify (G_OBJECT (text_tag), "underline_set");
1076       break;
1077
1078     case PROP_RISE:
1079       text_tag->rise_set = TRUE;
1080       text_tag->values->appearance.rise = g_value_get_int (value);
1081       g_object_notify (G_OBJECT (text_tag), "rise_set");
1082       size_changed = TRUE;      
1083       break;
1084
1085     case PROP_BG_FULL_HEIGHT:
1086       text_tag->bg_full_height_set = TRUE;
1087       text_tag->values->bg_full_height = g_value_get_boolean (value);
1088       g_object_notify (G_OBJECT (text_tag), "bg_full_height_set");
1089       break;
1090
1091     case PROP_LANGUAGE:
1092       text_tag->language_set = TRUE;
1093       text_tag->values->language = pango_language_from_string (g_value_get_string (value));
1094       g_object_notify (G_OBJECT (text_tag), "language_set");
1095       break;
1096
1097     case PROP_TABS:
1098       text_tag->tabs_set = TRUE;
1099
1100       if (text_tag->values->tabs)
1101         pango_tab_array_free (text_tag->values->tabs);
1102
1103       /* FIXME I'm not sure if this is a memleak or not */
1104       text_tag->values->tabs =
1105         pango_tab_array_copy (g_value_get_boxed (value));
1106
1107       g_object_notify (G_OBJECT (text_tag), "tabs_set");
1108       
1109       size_changed = TRUE;
1110       break;
1111
1112     case PROP_INVISIBLE:
1113       text_tag->invisible_set = TRUE;
1114       text_tag->values->invisible = g_value_get_boolean (value);
1115       g_object_notify (G_OBJECT (text_tag), "invisible_set");
1116       size_changed = TRUE;
1117       break;
1118       
1119       /* Whether the value should be used... */
1120
1121     case PROP_BACKGROUND_SET:
1122       text_tag->bg_color_set = g_value_get_boolean (value);
1123       break;
1124
1125     case PROP_FOREGROUND_SET:
1126       text_tag->fg_color_set = g_value_get_boolean (value);
1127       break;
1128
1129     case PROP_BACKGROUND_STIPPLE_SET:
1130       text_tag->bg_stipple_set = g_value_get_boolean (value);
1131       if (!text_tag->bg_stipple_set &&
1132           text_tag->values->appearance.bg_stipple)
1133         {
1134           g_object_unref (G_OBJECT (text_tag->values->appearance.bg_stipple));
1135           text_tag->values->appearance.bg_stipple = NULL;
1136         }
1137       break;
1138
1139     case PROP_FOREGROUND_STIPPLE_SET:
1140       text_tag->fg_stipple_set = g_value_get_boolean (value);
1141       if (!text_tag->fg_stipple_set &&
1142           text_tag->values->appearance.fg_stipple)
1143         {
1144           g_object_unref (G_OBJECT (text_tag->values->appearance.fg_stipple));
1145           text_tag->values->appearance.fg_stipple = NULL;
1146         }
1147       break;
1148
1149     case PROP_FAMILY_SET:
1150       text_tag->family_set = g_value_get_boolean (value);
1151       size_changed = TRUE;
1152       break;
1153
1154     case PROP_STYLE_SET:
1155       text_tag->style_set = g_value_get_boolean (value);
1156       size_changed = TRUE;
1157       break;
1158
1159     case PROP_VARIANT_SET:
1160       text_tag->variant_set = g_value_get_boolean (value);
1161       size_changed = TRUE;
1162       break;
1163
1164     case PROP_WEIGHT_SET:
1165       text_tag->weight_set = g_value_get_boolean (value);
1166       size_changed = TRUE;
1167       break;
1168
1169     case PROP_STRETCH_SET:
1170       text_tag->stretch_set = g_value_get_boolean (value);
1171       size_changed = TRUE;
1172       break;
1173
1174     case PROP_SIZE_SET:
1175       text_tag->size_set = g_value_get_boolean (value);
1176       size_changed = TRUE;
1177       break;
1178
1179     case PROP_SCALE_SET:
1180       text_tag->scale_set = g_value_get_boolean (value);
1181       size_changed = TRUE;
1182       break;
1183       
1184     case PROP_PIXELS_ABOVE_LINES_SET:
1185       text_tag->pixels_above_lines_set = g_value_get_boolean (value);
1186       size_changed = TRUE;
1187       break;
1188
1189     case PROP_PIXELS_BELOW_LINES_SET:
1190       text_tag->pixels_below_lines_set = g_value_get_boolean (value);
1191       size_changed = TRUE;
1192       break;
1193
1194     case PROP_PIXELS_INSIDE_WRAP_SET:
1195       text_tag->pixels_inside_wrap_set = g_value_get_boolean (value);
1196       size_changed = TRUE;
1197       break;
1198
1199     case PROP_EDITABLE_SET:
1200       text_tag->editable_set = g_value_get_boolean (value);
1201       break;
1202
1203     case PROP_WRAP_MODE_SET:
1204       text_tag->wrap_mode_set = g_value_get_boolean (value);
1205       size_changed = TRUE;
1206       break;
1207
1208     case PROP_JUSTIFICATION_SET:
1209       text_tag->justification_set = g_value_get_boolean (value);
1210       size_changed = TRUE;
1211       break;
1212       
1213     case PROP_LEFT_MARGIN_SET:
1214       text_tag->left_margin_set = g_value_get_boolean (value);
1215       size_changed = TRUE;
1216       break;
1217
1218     case PROP_INDENT_SET:
1219       text_tag->indent_set = g_value_get_boolean (value);
1220       size_changed = TRUE;
1221       break;
1222
1223     case PROP_STRIKETHROUGH_SET:
1224       text_tag->strikethrough_set = g_value_get_boolean (value);
1225       break;
1226
1227     case PROP_RIGHT_MARGIN_SET:
1228       text_tag->right_margin_set = g_value_get_boolean (value);
1229       size_changed = TRUE;
1230       break;
1231
1232     case PROP_UNDERLINE_SET:
1233       text_tag->underline_set = g_value_get_boolean (value);
1234       break;
1235
1236     case PROP_RISE_SET:
1237       text_tag->rise_set = g_value_get_boolean (value);
1238       size_changed = TRUE;
1239       break;
1240
1241     case PROP_BG_FULL_HEIGHT_SET:
1242       text_tag->bg_full_height_set = g_value_get_boolean (value);
1243       break;
1244
1245     case PROP_LANGUAGE_SET:
1246       text_tag->language_set = g_value_get_boolean (value);
1247       size_changed = TRUE;
1248       break;
1249
1250     case PROP_TABS_SET:
1251       text_tag->tabs_set = g_value_get_boolean (value);
1252       size_changed = TRUE;
1253       break;
1254
1255     case PROP_INVISIBLE_SET:
1256       text_tag->invisible_set = g_value_get_boolean (value);
1257       size_changed = TRUE;
1258       break;
1259       
1260     default:
1261       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1262       break;
1263     }
1264
1265   /* FIXME I would like to do this after all set_property in a single
1266    * g_object_set () have been called. But an idle function won't
1267    * work; we need to emit when the tag is changed, not when we get
1268    * around to the event loop. So blah, we eat some inefficiency.
1269    */
1270
1271   /* This is also somewhat weird since we emit another object's
1272    * signal here, but the two objects are already tightly bound.
1273    */
1274
1275   if (text_tag->table)
1276     g_signal_emit_by_name (G_OBJECT (text_tag->table),
1277                            "tag_changed",
1278                            text_tag, size_changed);
1279 }
1280
1281 static void
1282 get_color_arg (GValue *value, GdkColor *orig)
1283 {
1284   GdkColor *color;
1285
1286   color = g_new (GdkColor, 1);
1287   *color = *orig;
1288   g_value_init (value, GDK_TYPE_COLOR);
1289   g_value_set_boxed (value, color);
1290 }
1291
1292 static void
1293 gtk_text_tag_get_property (GObject      *object,
1294                            guint         prop_id,
1295                            GValue       *value,
1296                            GParamSpec   *pspec)
1297 {
1298   GtkTextTag *tag;
1299
1300   tag = GTK_TEXT_TAG (object);
1301
1302   switch (prop_id)
1303     {
1304     case PROP_NAME:
1305       g_value_set_string (value, tag->name);
1306       break;
1307
1308     case PROP_BACKGROUND_GDK:
1309       get_color_arg (value, &tag->values->appearance.bg_color);
1310       break;
1311
1312     case PROP_FOREGROUND_GDK:
1313       get_color_arg (value, &tag->values->appearance.fg_color);
1314       break;
1315
1316     case PROP_BACKGROUND_STIPPLE:
1317       if (tag->bg_stipple_set)
1318         g_value_set_boxed (value, tag->values->appearance.bg_stipple);
1319       break;
1320
1321     case PROP_FOREGROUND_STIPPLE:
1322       if (tag->fg_stipple_set)
1323         g_value_set_boxed (value, tag->values->appearance.fg_stipple);
1324       break;
1325
1326     case PROP_FONT:
1327         {
1328           /* FIXME GValue imposes a totally gratuitous string copy
1329            * here, we could just hand off string ownership
1330            */
1331           gchar *str = pango_font_description_to_string (&tag->values->font);
1332           g_value_set_string (value, str);
1333           g_free (str);
1334         }
1335       break;
1336
1337     case PROP_FONT_DESC:
1338       g_value_set_boxed (value, &tag->values->font);
1339       break;
1340
1341     case PROP_FAMILY:
1342       g_value_set_string (value, tag->values->font.family_name);
1343       break;
1344
1345     case PROP_STYLE:
1346       g_value_set_enum (value, tag->values->font.style);
1347       break;
1348
1349     case PROP_VARIANT:
1350       g_value_set_enum (value, tag->values->font.variant);
1351       break;
1352
1353     case PROP_WEIGHT:
1354       g_value_set_int (value, tag->values->font.weight);
1355       break;
1356
1357     case PROP_STRETCH:
1358       g_value_set_enum (value, tag->values->font.stretch);
1359       break;
1360
1361     case PROP_SIZE:
1362       g_value_set_int (value,  tag->values->font.size);
1363       break;
1364       
1365     case PROP_SIZE_POINTS:
1366       g_value_set_double (value, ((double)tag->values->font.size) / (double)PANGO_SCALE);
1367       break;
1368
1369     case PROP_SCALE:
1370       g_value_set_double (value, tag->values->font_scale);
1371       break;
1372       
1373     case PROP_PIXELS_ABOVE_LINES:
1374       g_value_set_int (value,  tag->values->pixels_above_lines);
1375       break;
1376
1377     case PROP_PIXELS_BELOW_LINES:
1378       g_value_set_int (value,  tag->values->pixels_below_lines);
1379       break;
1380
1381     case PROP_PIXELS_INSIDE_WRAP:
1382       g_value_set_int (value,  tag->values->pixels_inside_wrap);
1383       break;
1384
1385     case PROP_EDITABLE:
1386       g_value_set_boolean (value, tag->values->editable);
1387       break;
1388
1389     case PROP_WRAP_MODE:
1390       g_value_set_enum (value, tag->values->wrap_mode);
1391       break;
1392
1393     case PROP_JUSTIFICATION:
1394       g_value_set_enum (value, tag->values->justification);
1395       break;
1396
1397     case PROP_DIRECTION:
1398       g_value_set_enum (value, tag->values->direction);
1399       break;
1400       
1401     case PROP_LEFT_MARGIN:
1402       g_value_set_int (value,  tag->values->left_margin);
1403       break;
1404
1405     case PROP_INDENT:
1406       g_value_set_int (value,  tag->values->indent);
1407       break;
1408
1409     case PROP_STRIKETHROUGH:
1410       g_value_set_boolean (value, tag->values->appearance.strikethrough);
1411       break;
1412
1413     case PROP_RIGHT_MARGIN:
1414       g_value_set_int (value, tag->values->right_margin);
1415       break;
1416
1417     case PROP_UNDERLINE:
1418       g_value_set_enum (value, tag->values->appearance.underline);
1419       break;
1420
1421     case PROP_RISE:
1422       g_value_set_int (value, tag->values->appearance.rise);
1423       break;
1424
1425     case PROP_BG_FULL_HEIGHT:
1426       g_value_set_boolean (value, tag->values->bg_full_height);
1427       break;
1428
1429     case PROP_LANGUAGE:
1430       g_value_set_string (value, pango_language_to_string (tag->values->language));
1431       break;
1432
1433     case PROP_TABS:
1434       if (tag->values->tabs)
1435         g_value_set_boxed (value, tag->values->tabs);
1436       break;
1437
1438     case PROP_INVISIBLE:
1439       g_value_set_boolean (value, tag->values->invisible);
1440       break;
1441       
1442     case PROP_BACKGROUND_SET:
1443       g_value_set_boolean (value, tag->bg_color_set);
1444       break;
1445
1446     case PROP_FOREGROUND_SET:
1447       g_value_set_boolean (value, tag->fg_color_set);
1448       break;
1449
1450     case PROP_BACKGROUND_STIPPLE_SET:
1451       g_value_set_boolean (value, tag->bg_stipple_set);
1452       break;
1453
1454     case PROP_FOREGROUND_STIPPLE_SET:
1455       g_value_set_boolean (value, tag->fg_stipple_set);
1456       break;
1457
1458     case PROP_FAMILY_SET:
1459       g_value_set_boolean (value, tag->family_set);
1460       break;
1461
1462     case PROP_STYLE_SET:
1463       g_value_set_boolean (value, tag->style_set);
1464       break;
1465
1466     case PROP_VARIANT_SET:
1467       g_value_set_boolean (value, tag->variant_set);
1468       break;
1469
1470     case PROP_WEIGHT_SET:
1471       g_value_set_boolean (value, tag->weight_set);
1472       break;
1473
1474     case PROP_STRETCH_SET:
1475       g_value_set_boolean (value, tag->stretch_set);
1476       break;
1477
1478     case PROP_SIZE_SET:
1479       g_value_set_boolean (value, tag->size_set);
1480       break;
1481
1482     case PROP_SCALE_SET:
1483       g_value_set_boolean (value, tag->scale_set);
1484       break;
1485       
1486     case PROP_PIXELS_ABOVE_LINES_SET:
1487       g_value_set_boolean (value, tag->pixels_above_lines_set);
1488       break;
1489
1490     case PROP_PIXELS_BELOW_LINES_SET:
1491       g_value_set_boolean (value, tag->pixels_below_lines_set);
1492       break;
1493
1494     case PROP_PIXELS_INSIDE_WRAP_SET:
1495       g_value_set_boolean (value, tag->pixels_inside_wrap_set);
1496       break;
1497
1498     case PROP_EDITABLE_SET:
1499       g_value_set_boolean (value, tag->editable_set);
1500       break;
1501
1502     case PROP_WRAP_MODE_SET:
1503       g_value_set_boolean (value, tag->wrap_mode_set);
1504       break;
1505
1506     case PROP_JUSTIFICATION_SET:
1507       g_value_set_boolean (value, tag->justification_set);
1508       break;
1509       
1510     case PROP_LEFT_MARGIN_SET:
1511       g_value_set_boolean (value, tag->left_margin_set);
1512       break;
1513
1514     case PROP_INDENT_SET:
1515       g_value_set_boolean (value, tag->indent_set);
1516       break;
1517
1518     case PROP_STRIKETHROUGH_SET:
1519       g_value_set_boolean (value, tag->strikethrough_set);
1520       break;
1521
1522     case PROP_RIGHT_MARGIN_SET:
1523       g_value_set_boolean (value, tag->right_margin_set);
1524       break;
1525
1526     case PROP_UNDERLINE_SET:
1527       g_value_set_boolean (value, tag->underline_set);
1528       break;
1529
1530     case PROP_RISE_SET:
1531       g_value_set_boolean (value, tag->rise_set);
1532       break;
1533
1534     case PROP_BG_FULL_HEIGHT_SET:
1535       g_value_set_boolean (value, tag->bg_full_height_set);
1536       break;
1537
1538     case PROP_LANGUAGE_SET:
1539       g_value_set_boolean (value, tag->language_set);
1540       break;
1541
1542     case PROP_TABS_SET:
1543       g_value_set_boolean (value, tag->tabs_set);
1544       break;
1545
1546     case PROP_INVISIBLE_SET:
1547       g_value_set_boolean (value, tag->invisible_set);
1548       break;
1549       
1550     case PROP_BACKGROUND:
1551     case PROP_FOREGROUND:
1552       g_warning ("'foreground' and 'background' properties are not readable, use 'foreground_gdk' and 'background_gdk'");
1553     default:
1554       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1555       break;
1556     }
1557 }
1558
1559 /*
1560  * Tag operations
1561  */
1562
1563 typedef struct {
1564   gint high;
1565   gint low;
1566   gint delta;
1567 } DeltaData;
1568
1569 static void
1570 delta_priority_foreach (GtkTextTag *tag, gpointer user_data)
1571 {
1572   DeltaData *dd = user_data;
1573
1574   if (tag->priority >= dd->low && tag->priority <= dd->high)
1575     tag->priority += dd->delta;
1576 }
1577
1578 /**
1579  * gtk_text_tag_get_priority:
1580  * @tag: a #GtkTextTag
1581  * 
1582  * Get the tag priority.
1583  * 
1584  * Return value: The tag's priority.
1585  **/
1586 gint
1587 gtk_text_tag_get_priority (GtkTextTag *tag)
1588 {
1589   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), 0);
1590
1591   return tag->priority;
1592 }
1593
1594 /**
1595  * gtk_text_tag_set_priority:
1596  * @tag: a #GtkTextTag
1597  * @priority: the new priority
1598  * 
1599  * Sets the priority of a #GtkTextTag. Valid priorities are
1600  * start at 0 and go to one less than gtk_text_tag_table_size().
1601  * Each tag in a table has a unique priority; setting the priority
1602  * of one tag shifts the priorities of all the other tags in the
1603  * table to maintain a unique priority for each tag. Higher priority
1604  * tags "win" if two tags both set the same text attribute. When adding
1605  * a tag to a tag table, it will be assigned the highest priority in
1606  * the table by default; so normally the precedence of a set of tags
1607  * is the order in which they were added to the table, or created with
1608  * gtk_text_buffer_create_tag(), which adds the tag to the buffer's table
1609  * automatically.
1610  **/
1611 void
1612 gtk_text_tag_set_priority (GtkTextTag *tag,
1613                            gint        priority)
1614 {
1615   DeltaData dd;
1616
1617   g_return_if_fail (GTK_IS_TEXT_TAG (tag));
1618   g_return_if_fail (tag->table != NULL);
1619   g_return_if_fail (priority >= 0);
1620   g_return_if_fail (priority < gtk_text_tag_table_size (tag->table));
1621
1622   if (priority == tag->priority)
1623     return;
1624
1625   if (priority < tag->priority)
1626     {
1627       dd.low = priority;
1628       dd.high = tag->priority - 1;
1629       dd.delta = 1;
1630     }
1631   else
1632     {
1633       dd.low = tag->priority + 1;
1634       dd.high = priority;
1635       dd.delta = -1;
1636     }
1637
1638   gtk_text_tag_table_foreach (tag->table,
1639                               delta_priority_foreach,
1640                               &dd);
1641
1642   tag->priority = priority;
1643 }
1644
1645 /**
1646  * gtk_text_tag_event:
1647  * @tag: a #GtkTextTag
1648  * @event_object: object that received the event, such as a widget
1649  * @event: the event
1650  * @iter: location where the event was received
1651  * 
1652  * Emits the "event" signal on the #GtkTextTag.
1653  * 
1654  * Return value: result of signal emission (whether the event was handled)
1655  **/
1656 gboolean
1657 gtk_text_tag_event (GtkTextTag        *tag,
1658                     GObject           *event_object,
1659                     GdkEvent          *event,
1660                     const GtkTextIter *iter)
1661 {
1662   gboolean retval = FALSE;
1663
1664   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
1665   g_return_val_if_fail (GTK_IS_OBJECT (event_object), FALSE);
1666   g_return_val_if_fail (event != NULL, FALSE);
1667
1668   g_signal_emit (G_OBJECT (tag),
1669                  signals[EVENT],
1670                  0,
1671                  event_object,
1672                  event,
1673                  iter,
1674                  &retval);
1675
1676   return retval;
1677 }
1678
1679 static int
1680 tag_sort_func (gconstpointer first, gconstpointer second)
1681 {
1682   GtkTextTag *tag1, *tag2;
1683
1684   tag1 = * (GtkTextTag **) first;
1685   tag2 = * (GtkTextTag **) second;
1686   return tag1->priority - tag2->priority;
1687 }
1688
1689 void
1690 _gtk_text_tag_array_sort (GtkTextTag** tag_array_p,
1691                           guint len)
1692 {
1693   int i, j, prio;
1694   GtkTextTag **tag;
1695   GtkTextTag **maxPtrPtr, *tmp;
1696
1697   g_return_if_fail (tag_array_p != NULL);
1698   g_return_if_fail (len > 0);
1699
1700   if (len < 2) {
1701     return;
1702   }
1703   if (len < 20) {
1704     GtkTextTag **iter = tag_array_p;
1705
1706     for (i = len-1; i > 0; i--, iter++) {
1707       maxPtrPtr = tag = iter;
1708       prio = tag[0]->priority;
1709       for (j = i, tag++; j > 0; j--, tag++) {
1710         if (tag[0]->priority < prio) {
1711           prio = tag[0]->priority;
1712           maxPtrPtr = tag;
1713         }
1714       }
1715       tmp = *maxPtrPtr;
1716       *maxPtrPtr = *iter;
1717       *iter = tmp;
1718     }
1719   } else {
1720     qsort ((void *) tag_array_p, (unsigned) len, sizeof (GtkTextTag *),
1721            tag_sort_func);
1722   }
1723
1724 #if 0
1725   {
1726     printf ("Sorted tag array: \n");
1727     i = 0;
1728     while (i < len)
1729       {
1730         GtkTextTag *t = tag_array_p[i];
1731         printf ("  %s priority %d\n", t->name, t->priority);
1732
1733         ++i;
1734       }
1735   }
1736 #endif
1737 }
1738
1739 /*
1740  * Attributes
1741  */
1742
1743 /**
1744  * gtk_text_attributes_new:
1745  * 
1746  * Creates a #GtkTextAttributes, which describes
1747  * a set of properties on some text.
1748  * 
1749  * Return value: a new #GtkTextAttributes
1750  **/
1751 GtkTextAttributes*
1752 gtk_text_attributes_new (void)
1753 {
1754   GtkTextAttributes *values;
1755
1756   values = g_new0 (GtkTextAttributes, 1);
1757
1758   /* 0 is a valid value for most of the struct */
1759
1760   values->refcount = 1;
1761
1762   values->language = gtk_get_default_language ();
1763
1764   values->font_scale = 1.0;
1765   
1766   return values;
1767 }
1768
1769 /**
1770  * gtk_text_attributes_copy:
1771  * @src: a #GtkTextAttributes to be copied
1772  * 
1773  * Copies @src and returns a new #GtkTextAttributes.
1774  * 
1775  * Return value: a copy of @src
1776  **/
1777 GtkTextAttributes*
1778 gtk_text_attributes_copy (GtkTextAttributes *src)
1779 {
1780   GtkTextAttributes *dest;
1781
1782   dest = gtk_text_attributes_new ();
1783   gtk_text_attributes_copy_values (src, dest);
1784
1785   return dest;
1786 }
1787
1788 /**
1789  * gtk_text_attributes_copy_values:
1790  * @src: a #GtkTextAttributes
1791  * @dest: another #GtkTextAttributes
1792  * 
1793  * Copies the values from @src to @dest so that @dest has the same values
1794  * as @src. Frees existing values in @dest.
1795  **/
1796 void
1797 gtk_text_attributes_copy_values (GtkTextAttributes *src,
1798                                  GtkTextAttributes *dest)
1799 {
1800   guint orig_refcount;
1801
1802   g_return_if_fail (!dest->realized);
1803
1804   if (src == dest)
1805     return;
1806
1807   /* Add refs */
1808
1809   if (src->appearance.bg_stipple)
1810     gdk_bitmap_ref (src->appearance.bg_stipple);
1811
1812   if (src->appearance.fg_stipple)
1813     gdk_bitmap_ref (src->appearance.fg_stipple);
1814
1815   /* Remove refs */
1816
1817   if (dest->appearance.bg_stipple)
1818     gdk_bitmap_unref (dest->appearance.bg_stipple);
1819
1820   if (dest->appearance.fg_stipple)
1821     gdk_bitmap_unref (dest->appearance.fg_stipple);
1822
1823   if (dest->font.family_name)
1824     g_free (dest->font.family_name);
1825   
1826   /* Copy */
1827   orig_refcount = dest->refcount;
1828
1829   *dest = *src;
1830
1831   if (src->tabs)
1832     dest->tabs = pango_tab_array_copy (src->tabs);
1833
1834   dest->language = src->language;
1835
1836   dest->font.family_name = g_strdup (src->font.family_name);
1837   
1838   dest->refcount = orig_refcount;
1839   dest->realized = FALSE;
1840 }
1841
1842 /**
1843  * gtk_text_attributes_ref:
1844  * @values: a #GtkTextAttributes
1845  * 
1846  * Increments the reference count on @values.
1847  **/
1848 void
1849 gtk_text_attributes_ref (GtkTextAttributes *values)
1850 {
1851   g_return_if_fail (values != NULL);
1852
1853   values->refcount += 1;
1854 }
1855
1856 /**
1857  * gtk_text_attributes_unref:
1858  * @values: a #GtkTextAttributes
1859  * 
1860  * Decrements the reference count on @values, freeing the structure
1861  * if the reference count reaches 0.
1862  **/
1863 void
1864 gtk_text_attributes_unref (GtkTextAttributes *values)
1865 {
1866   g_return_if_fail (values != NULL);
1867   g_return_if_fail (values->refcount > 0);
1868
1869   values->refcount -= 1;
1870
1871   if (values->refcount == 0)
1872     {
1873       g_assert (!values->realized);
1874
1875       if (values->appearance.bg_stipple)
1876         gdk_bitmap_unref (values->appearance.bg_stipple);
1877
1878       if (values->appearance.fg_stipple)
1879         gdk_bitmap_unref (values->appearance.fg_stipple);
1880
1881       if (values->tabs)
1882         pango_tab_array_free (values->tabs);
1883
1884       if (values->font.family_name)
1885         g_free (values->font.family_name);
1886       
1887       g_free (values);
1888     }
1889 }
1890
1891 void
1892 _gtk_text_attributes_realize (GtkTextAttributes *values,
1893                               GdkColormap *cmap,
1894                               GdkVisual *visual)
1895 {
1896   g_return_if_fail (values != NULL);
1897   g_return_if_fail (values->refcount > 0);
1898   g_return_if_fail (!values->realized);
1899
1900   /* It is wrong to use this colormap, FIXME */
1901   gdk_colormap_alloc_color (cmap,
1902                             &values->appearance.fg_color,
1903                             FALSE, TRUE);
1904
1905   gdk_colormap_alloc_color (cmap,
1906                             &values->appearance.bg_color,
1907                             FALSE, TRUE);
1908
1909   values->realized = TRUE;
1910 }
1911
1912 void
1913 _gtk_text_attributes_unrealize (GtkTextAttributes *values,
1914                                 GdkColormap *cmap,
1915                                 GdkVisual *visual)
1916 {
1917   g_return_if_fail (values != NULL);
1918   g_return_if_fail (values->refcount > 0);
1919   g_return_if_fail (values->realized);
1920
1921   gdk_colormap_free_colors (cmap,
1922                             &values->appearance.fg_color, 1);
1923
1924
1925   gdk_colormap_free_colors (cmap,
1926                             &values->appearance.bg_color, 1);
1927
1928   values->appearance.fg_color.pixel = 0;
1929   values->appearance.bg_color.pixel = 0;
1930
1931   values->realized = FALSE;
1932 }
1933
1934 void
1935 _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
1936                                      GtkTextTag**       tags,
1937                                      guint              n_tags)
1938 {
1939   guint n = 0;
1940
1941   g_return_if_fail (!dest->realized);
1942
1943   while (n < n_tags)
1944     {
1945       GtkTextTag *tag = tags[n];
1946       GtkTextAttributes *vals = tag->values;
1947
1948       if (n > 0)
1949         g_assert (tags[n]->priority > tags[n-1]->priority);
1950
1951       if (tag->bg_color_set)
1952         {
1953           dest->appearance.bg_color = vals->appearance.bg_color;
1954
1955           dest->appearance.draw_bg = TRUE;
1956         }
1957       if (tag->fg_color_set)
1958         dest->appearance.fg_color = vals->appearance.fg_color;
1959       
1960       if (tag->bg_stipple_set)
1961         {
1962           gdk_bitmap_ref (vals->appearance.bg_stipple);
1963           if (dest->appearance.bg_stipple)
1964             gdk_bitmap_unref (dest->appearance.bg_stipple);
1965           dest->appearance.bg_stipple = vals->appearance.bg_stipple;
1966
1967           dest->appearance.draw_bg = TRUE;
1968         }
1969
1970       if (tag->fg_stipple_set)
1971         {
1972           gdk_bitmap_ref (vals->appearance.fg_stipple);
1973           if (dest->appearance.fg_stipple)
1974             gdk_bitmap_unref (dest->appearance.fg_stipple);
1975           dest->appearance.fg_stipple = vals->appearance.fg_stipple;
1976         }
1977
1978       if (tag->family_set)
1979         {
1980           if (dest->font.family_name)
1981             g_free (dest->font.family_name);
1982
1983           dest->font.family_name = g_strdup (vals->font.family_name);
1984         }
1985
1986       if (tag->style_set)
1987         dest->font.style = vals->font.style;
1988
1989       if (tag->variant_set)
1990         dest->font.variant = vals->font.variant;
1991
1992       if (tag->weight_set)
1993         dest->font.weight = vals->font.weight;
1994
1995       if (tag->stretch_set)
1996         dest->font.stretch = vals->font.stretch;
1997
1998       if (tag->size_set)
1999         dest->font.size = vals->font.size;
2000
2001       /* multiply all the scales together to get a composite */
2002       if (tag->scale_set)
2003         dest->font_scale *= vals->font_scale;
2004       
2005       if (tag->justification_set)
2006         dest->justification = vals->justification;
2007
2008       if (vals->direction != GTK_TEXT_DIR_NONE)
2009         dest->direction = vals->direction;
2010
2011       if (tag->left_margin_set)
2012         dest->left_margin = vals->left_margin;
2013
2014       if (tag->indent_set)
2015         dest->indent = vals->indent;
2016
2017       if (tag->rise_set)
2018         dest->appearance.rise = vals->appearance.rise;
2019
2020       if (tag->right_margin_set)
2021         dest->right_margin = vals->right_margin;
2022
2023       if (tag->pixels_above_lines_set)
2024         dest->pixels_above_lines = vals->pixels_above_lines;
2025
2026       if (tag->pixels_below_lines_set)
2027         dest->pixels_below_lines = vals->pixels_below_lines;
2028
2029       if (tag->pixels_inside_wrap_set)
2030         dest->pixels_inside_wrap = vals->pixels_inside_wrap;
2031
2032       if (tag->tabs_set)
2033         {
2034           if (dest->tabs)
2035             pango_tab_array_free (dest->tabs);
2036           dest->tabs = pango_tab_array_copy (vals->tabs);
2037         }
2038
2039       if (tag->wrap_mode_set)
2040         dest->wrap_mode = vals->wrap_mode;
2041
2042       if (tag->underline_set)
2043         dest->appearance.underline = vals->appearance.underline;
2044
2045       if (tag->strikethrough_set)
2046         dest->appearance.strikethrough = vals->appearance.strikethrough;
2047
2048       if (tag->invisible_set)
2049         dest->invisible = vals->invisible;
2050
2051       if (tag->editable_set)
2052         dest->editable = vals->editable;
2053
2054       if (tag->bg_full_height_set)
2055         dest->bg_full_height = vals->bg_full_height;
2056
2057       if (tag->language_set)
2058         dest->language = vals->language;
2059
2060       ++n;
2061     }
2062 }
2063
2064 gboolean
2065 _gtk_text_tag_affects_size (GtkTextTag *tag)
2066 {
2067   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
2068
2069   return
2070     tag->family_set ||
2071     tag->style_set ||
2072     tag->variant_set ||
2073     tag->weight_set ||
2074     tag->size_set ||
2075     tag->scale_set ||
2076     tag->stretch_set ||
2077     tag->justification_set ||
2078     tag->left_margin_set ||
2079     tag->indent_set ||
2080     tag->rise_set ||
2081     tag->right_margin_set ||
2082     tag->pixels_above_lines_set ||
2083     tag->pixels_below_lines_set ||
2084     tag->pixels_inside_wrap_set ||
2085     tag->tabs_set ||
2086     tag->underline_set ||
2087     tag->wrap_mode_set ||
2088     tag->invisible_set;
2089 }
2090
2091 gboolean
2092 _gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag)
2093 {
2094   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
2095
2096   return
2097     tag->bg_color_set ||
2098     tag->bg_stipple_set ||
2099     tag->fg_color_set ||
2100     tag->fg_stipple_set ||
2101     tag->strikethrough_set ||
2102     tag->bg_full_height_set;
2103 }