]> Pileus Git - ~andy/gtk/blob - gtk/gtktexttag.c
fix some shell typos
[~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                                                        GTK_TYPE_PANGO_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                                                        GTK_TYPE_PANGO_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_newc ("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,
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       if (text_tag->family_set)
760         {
761           text_tag->family_set = FALSE;
762           g_object_notify (G_OBJECT (text_tag), "family_set");
763         }
764       if (text_tag->style_set)
765         {
766           text_tag->style_set = FALSE;
767           g_object_notify (G_OBJECT (text_tag), "style_set");
768         }
769       if (text_tag->variant_set)
770         {
771           text_tag->variant_set = FALSE;
772           g_object_notify (G_OBJECT (text_tag), "variant_set");
773         }
774       if (text_tag->weight_set)
775         {
776           text_tag->weight_set = FALSE;
777           g_object_notify (G_OBJECT (text_tag), "weight_set");
778         }
779       if (text_tag->stretch_set)
780         {
781           text_tag->stretch_set = FALSE;
782           g_object_notify (G_OBJECT (text_tag), "stretch_set");
783         }
784       if (text_tag->size_set)
785         {
786           text_tag->size_set = FALSE;
787           g_object_notify (G_OBJECT (text_tag), "size_set");
788         }
789     }
790 }
791
792 static void
793 gtk_text_tag_set_property (GObject      *object,
794                            guint         prop_id,
795                            const GValue *value,
796                            GParamSpec   *pspec)
797 {
798   GtkTextTag *text_tag;
799   gboolean size_changed = FALSE;
800
801   text_tag = GTK_TEXT_TAG (object);
802
803   g_return_if_fail (!text_tag->values->realized);
804
805   switch (prop_id)
806     {
807     case PROP_NAME:
808       g_return_if_fail (text_tag->name == NULL);
809       text_tag->name = g_strdup (g_value_get_string (value));
810       break;
811
812     case PROP_BACKGROUND:
813       {
814         GdkColor color;
815
816         if (gdk_color_parse (g_value_get_string (value), &color))
817           set_bg_color (text_tag, &color);
818         else
819           g_warning ("Don't know color `%s'", g_value_get_string (value));
820
821         g_object_notify (G_OBJECT (text_tag), "background_gdk");
822       }
823       break;
824
825     case PROP_FOREGROUND:
826       {
827         GdkColor color;
828
829         if (gdk_color_parse (g_value_get_string (value), &color))
830           set_fg_color (text_tag, &color);
831         else
832           g_warning ("Don't know color `%s'", g_value_get_string (value));
833
834         g_object_notify (G_OBJECT (text_tag), "foreground_gdk");
835       }
836       break;
837
838     case PROP_BACKGROUND_GDK:
839       {
840         GdkColor *color = g_value_get_boxed (value);
841
842         set_bg_color (text_tag, color);
843       }
844       break;
845
846     case PROP_FOREGROUND_GDK:
847       {
848         GdkColor *color = g_value_get_boxed (value);
849
850         set_fg_color (text_tag, color);
851       }
852       break;
853
854     case PROP_BACKGROUND_STIPPLE:
855       {
856         GdkBitmap *bitmap = g_value_get_object (value);
857
858         text_tag->bg_stipple_set = TRUE;
859         g_object_notify (G_OBJECT (text_tag), "background_stipple_set");
860         
861         if (text_tag->values->appearance.bg_stipple != bitmap)
862           {
863             if (bitmap != NULL)
864               gdk_bitmap_ref (bitmap);
865
866             if (text_tag->values->appearance.bg_stipple)
867               gdk_bitmap_unref (text_tag->values->appearance.bg_stipple);
868
869             text_tag->values->appearance.bg_stipple = bitmap;
870           }
871       }
872       break;
873
874     case PROP_FOREGROUND_STIPPLE:
875       {
876         GdkBitmap *bitmap = g_value_get_object (value);
877
878         text_tag->fg_stipple_set = TRUE;
879         g_object_notify (G_OBJECT (text_tag), "foreground_stipple_set");
880
881         if (text_tag->values->appearance.fg_stipple != bitmap)
882           {
883             if (bitmap != NULL)
884               gdk_bitmap_ref (bitmap);
885
886             if (text_tag->values->appearance.fg_stipple)
887               gdk_bitmap_unref (text_tag->values->appearance.fg_stipple);
888
889             text_tag->values->appearance.fg_stipple = bitmap;
890           }
891       }
892       break;
893
894     case PROP_FONT:
895       {
896         PangoFontDescription *font_desc = NULL;
897         const gchar *name;
898
899         name = g_value_get_string (value);
900
901         if (name)
902           font_desc = pango_font_description_from_string (name);
903
904         set_font_description (text_tag, font_desc);
905         
906         if (font_desc)
907           pango_font_description_free (font_desc);
908         
909         size_changed = TRUE;
910       }
911       break;
912
913     case PROP_FONT_DESC:
914       {
915         PangoFontDescription *font_desc;
916
917         font_desc = g_value_get_boxed (value);
918
919         set_font_description (text_tag, font_desc);
920
921         size_changed = TRUE;
922       }
923       break;
924
925     case PROP_FAMILY:
926       if (text_tag->values->font.family_name)
927         g_free (text_tag->values->font.family_name);
928       text_tag->values->font.family_name = g_strdup (g_value_get_string (value));
929       text_tag->family_set = TRUE;
930       g_object_notify (G_OBJECT (text_tag), "family_set");
931       g_object_notify (G_OBJECT (text_tag), "font_desc");
932       g_object_notify (G_OBJECT (text_tag), "font");
933       size_changed = TRUE;
934       break;
935
936     case PROP_STYLE:
937       text_tag->values->font.style = g_value_get_enum (value);
938       text_tag->style_set = TRUE;
939       g_object_notify (G_OBJECT (text_tag), "style_set");
940       g_object_notify (G_OBJECT (text_tag), "font_desc");
941       g_object_notify (G_OBJECT (text_tag), "font");
942       size_changed = TRUE;
943       break;
944
945     case PROP_VARIANT:
946       text_tag->values->font.variant = g_value_get_enum (value);
947       text_tag->variant_set = TRUE;
948       g_object_notify (G_OBJECT (text_tag), "variant_set");
949       g_object_notify (G_OBJECT (text_tag), "font_desc");
950       g_object_notify (G_OBJECT (text_tag), "font");
951       size_changed = TRUE;
952       break;
953
954     case PROP_WEIGHT:
955       text_tag->values->font.weight = g_value_get_int (value);
956       text_tag->weight_set = TRUE;
957       g_object_notify (G_OBJECT (text_tag), "weight_set");
958       g_object_notify (G_OBJECT (text_tag), "font_desc");
959       g_object_notify (G_OBJECT (text_tag), "font");
960       size_changed = TRUE;
961       break;
962
963     case PROP_STRETCH:
964       text_tag->values->font.stretch = g_value_get_enum (value);
965       text_tag->stretch_set = TRUE;
966       g_object_notify (G_OBJECT (text_tag), "stretch_set");
967       g_object_notify (G_OBJECT (text_tag), "font_desc");
968       g_object_notify (G_OBJECT (text_tag), "font");
969       size_changed = TRUE;
970       break;
971
972     case PROP_SIZE:
973       text_tag->values->font.size = g_value_get_int (value);
974       text_tag->size_set = TRUE;
975       g_object_notify (G_OBJECT (text_tag), "size_points");
976       g_object_notify (G_OBJECT (text_tag), "size_set");
977       g_object_notify (G_OBJECT (text_tag), "font_desc");
978       g_object_notify (G_OBJECT (text_tag), "font");
979       size_changed = TRUE;
980       break;
981
982     case PROP_SCALE:
983       text_tag->values->font_scale = g_value_get_double (value);
984       text_tag->scale_set = TRUE;
985       size_changed = TRUE;
986       break;
987       
988     case PROP_SIZE_POINTS:
989       text_tag->values->font.size = g_value_get_double (value) * PANGO_SCALE;
990       text_tag->size_set = TRUE;
991       g_object_notify (G_OBJECT (text_tag), "size");
992       g_object_notify (G_OBJECT (text_tag), "size_set");
993       g_object_notify (G_OBJECT (text_tag), "font_desc");
994       g_object_notify (G_OBJECT (text_tag), "font");
995       size_changed = TRUE;
996       break;
997       
998     case PROP_PIXELS_ABOVE_LINES:
999       text_tag->pixels_above_lines_set = TRUE;
1000       text_tag->values->pixels_above_lines = g_value_get_int (value);
1001       g_object_notify (G_OBJECT (text_tag), "pixels_above_lines_set");
1002       size_changed = TRUE;
1003       break;
1004
1005     case PROP_PIXELS_BELOW_LINES:
1006       text_tag->pixels_below_lines_set = TRUE;
1007       text_tag->values->pixels_below_lines = g_value_get_int (value);
1008       g_object_notify (G_OBJECT (text_tag), "pixels_below_lines_set");
1009       size_changed = TRUE;
1010       break;
1011
1012     case PROP_PIXELS_INSIDE_WRAP:
1013       text_tag->pixels_inside_wrap_set = TRUE;
1014       text_tag->values->pixels_inside_wrap = g_value_get_int (value);
1015       g_object_notify (G_OBJECT (text_tag), "pixels_inside_wrap_set");
1016       size_changed = TRUE;
1017       break;
1018
1019     case PROP_EDITABLE:
1020       text_tag->editable_set = TRUE;
1021       text_tag->values->editable = g_value_get_boolean (value);
1022       g_object_notify (G_OBJECT (text_tag), "editable_set");
1023       break;
1024
1025     case PROP_WRAP_MODE:
1026       text_tag->wrap_mode_set = TRUE;
1027       text_tag->values->wrap_mode = g_value_get_enum (value);
1028       g_object_notify (G_OBJECT (text_tag), "wrap_mode_set");
1029       size_changed = TRUE;
1030       break;
1031
1032     case PROP_JUSTIFICATION:
1033       text_tag->justification_set = TRUE;
1034       text_tag->values->justification = g_value_get_enum (value);
1035       g_object_notify (G_OBJECT (text_tag), "justification_set");
1036       size_changed = TRUE;
1037       break;
1038
1039     case PROP_DIRECTION:
1040       text_tag->values->direction = g_value_get_enum (value);
1041       break;
1042
1043     case PROP_LEFT_MARGIN:
1044       text_tag->left_margin_set = TRUE;
1045       text_tag->values->left_margin = g_value_get_int (value);
1046       g_object_notify (G_OBJECT (text_tag), "left_margin_set");
1047       size_changed = TRUE;
1048       break;
1049
1050     case PROP_INDENT:
1051       text_tag->indent_set = TRUE;
1052       text_tag->values->indent = g_value_get_int (value);
1053       g_object_notify (G_OBJECT (text_tag), "indent_set");
1054       size_changed = TRUE;
1055       break;
1056
1057     case PROP_STRIKETHROUGH:
1058       text_tag->strikethrough_set = TRUE;
1059       text_tag->values->appearance.strikethrough = g_value_get_boolean (value);
1060       g_object_notify (G_OBJECT (text_tag), "strikethrough_set");
1061       break;
1062
1063     case PROP_RIGHT_MARGIN:
1064       text_tag->right_margin_set = TRUE;
1065       text_tag->values->right_margin = g_value_get_int (value);
1066       g_object_notify (G_OBJECT (text_tag), "right_margin_set");
1067       size_changed = TRUE;
1068       break;
1069
1070     case PROP_UNDERLINE:
1071       text_tag->underline_set = TRUE;
1072       text_tag->values->appearance.underline = g_value_get_enum (value);
1073       g_object_notify (G_OBJECT (text_tag), "underline_set");
1074       break;
1075
1076     case PROP_RISE:
1077       text_tag->rise_set = TRUE;
1078       text_tag->values->appearance.rise = g_value_get_int (value);
1079       g_object_notify (G_OBJECT (text_tag), "rise_set");
1080       size_changed = TRUE;      
1081       break;
1082
1083     case PROP_BG_FULL_HEIGHT:
1084       text_tag->bg_full_height_set = TRUE;
1085       text_tag->values->bg_full_height = g_value_get_boolean (value);
1086       g_object_notify (G_OBJECT (text_tag), "bg_full_height_set");
1087       break;
1088
1089     case PROP_LANGUAGE:
1090       text_tag->language_set = TRUE;
1091       text_tag->values->language = g_strdup (g_value_get_string (value));
1092       g_object_notify (G_OBJECT (text_tag), "language_set");
1093       break;
1094
1095     case PROP_TABS:
1096       text_tag->tabs_set = TRUE;
1097
1098       if (text_tag->values->tabs)
1099         pango_tab_array_free (text_tag->values->tabs);
1100
1101       /* FIXME I'm not sure if this is a memleak or not */
1102       text_tag->values->tabs =
1103         pango_tab_array_copy (g_value_get_boxed (value));
1104
1105       g_object_notify (G_OBJECT (text_tag), "tabs_set");
1106       
1107       size_changed = TRUE;
1108       break;
1109
1110     case PROP_INVISIBLE:
1111       text_tag->invisible_set = TRUE;
1112       text_tag->values->invisible = g_value_get_boolean (value);
1113       g_object_notify (G_OBJECT (text_tag), "invisible_set");
1114       size_changed = TRUE;
1115       break;
1116       
1117       /* Whether the value should be used... */
1118
1119     case PROP_BACKGROUND_SET:
1120       text_tag->bg_color_set = g_value_get_boolean (value);
1121       break;
1122
1123     case PROP_FOREGROUND_SET:
1124       text_tag->fg_color_set = g_value_get_boolean (value);
1125       break;
1126
1127     case PROP_BACKGROUND_STIPPLE_SET:
1128       text_tag->bg_stipple_set = g_value_get_boolean (value);
1129       if (!text_tag->bg_stipple_set &&
1130           text_tag->values->appearance.bg_stipple)
1131         {
1132           g_object_unref (G_OBJECT (text_tag->values->appearance.bg_stipple));
1133           text_tag->values->appearance.bg_stipple = NULL;
1134         }
1135       break;
1136
1137     case PROP_FOREGROUND_STIPPLE_SET:
1138       text_tag->fg_stipple_set = g_value_get_boolean (value);
1139       if (!text_tag->fg_stipple_set &&
1140           text_tag->values->appearance.fg_stipple)
1141         {
1142           g_object_unref (G_OBJECT (text_tag->values->appearance.fg_stipple));
1143           text_tag->values->appearance.fg_stipple = NULL;
1144         }
1145       break;
1146
1147     case PROP_FAMILY_SET:
1148       text_tag->family_set = g_value_get_boolean (value);
1149       size_changed = TRUE;
1150       break;
1151
1152     case PROP_STYLE_SET:
1153       text_tag->style_set = g_value_get_boolean (value);
1154       size_changed = TRUE;
1155       break;
1156
1157     case PROP_VARIANT_SET:
1158       text_tag->variant_set = g_value_get_boolean (value);
1159       size_changed = TRUE;
1160       break;
1161
1162     case PROP_WEIGHT_SET:
1163       text_tag->weight_set = g_value_get_boolean (value);
1164       size_changed = TRUE;
1165       break;
1166
1167     case PROP_STRETCH_SET:
1168       text_tag->stretch_set = g_value_get_boolean (value);
1169       size_changed = TRUE;
1170       break;
1171
1172     case PROP_SIZE_SET:
1173       text_tag->size_set = g_value_get_boolean (value);
1174       size_changed = TRUE;
1175       break;
1176
1177     case PROP_SCALE_SET:
1178       text_tag->scale_set = g_value_get_boolean (value);
1179       size_changed = TRUE;
1180       break;
1181       
1182     case PROP_PIXELS_ABOVE_LINES_SET:
1183       text_tag->pixels_above_lines_set = g_value_get_boolean (value);
1184       size_changed = TRUE;
1185       break;
1186
1187     case PROP_PIXELS_BELOW_LINES_SET:
1188       text_tag->pixels_below_lines_set = g_value_get_boolean (value);
1189       size_changed = TRUE;
1190       break;
1191
1192     case PROP_PIXELS_INSIDE_WRAP_SET:
1193       text_tag->pixels_inside_wrap_set = g_value_get_boolean (value);
1194       size_changed = TRUE;
1195       break;
1196
1197     case PROP_EDITABLE_SET:
1198       text_tag->editable_set = g_value_get_boolean (value);
1199       break;
1200
1201     case PROP_WRAP_MODE_SET:
1202       text_tag->wrap_mode_set = g_value_get_boolean (value);
1203       size_changed = TRUE;
1204       break;
1205
1206     case PROP_JUSTIFICATION_SET:
1207       text_tag->justification_set = g_value_get_boolean (value);
1208       size_changed = TRUE;
1209       break;
1210       
1211     case PROP_LEFT_MARGIN_SET:
1212       text_tag->left_margin_set = g_value_get_boolean (value);
1213       size_changed = TRUE;
1214       break;
1215
1216     case PROP_INDENT_SET:
1217       text_tag->indent_set = g_value_get_boolean (value);
1218       size_changed = TRUE;
1219       break;
1220
1221     case PROP_STRIKETHROUGH_SET:
1222       text_tag->strikethrough_set = g_value_get_boolean (value);
1223       break;
1224
1225     case PROP_RIGHT_MARGIN_SET:
1226       text_tag->right_margin_set = g_value_get_boolean (value);
1227       size_changed = TRUE;
1228       break;
1229
1230     case PROP_UNDERLINE_SET:
1231       text_tag->underline_set = g_value_get_boolean (value);
1232       break;
1233
1234     case PROP_RISE_SET:
1235       text_tag->rise_set = g_value_get_boolean (value);
1236       size_changed = TRUE;
1237       break;
1238
1239     case PROP_BG_FULL_HEIGHT_SET:
1240       text_tag->bg_full_height_set = g_value_get_boolean (value);
1241       break;
1242
1243     case PROP_LANGUAGE_SET:
1244       text_tag->language_set = g_value_get_boolean (value);
1245       size_changed = TRUE;
1246       break;
1247
1248     case PROP_TABS_SET:
1249       text_tag->tabs_set = g_value_get_boolean (value);
1250       size_changed = TRUE;
1251       break;
1252
1253     case PROP_INVISIBLE_SET:
1254       text_tag->invisible_set = g_value_get_boolean (value);
1255       size_changed = TRUE;
1256       break;
1257       
1258     default:
1259       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1260       break;
1261     }
1262
1263   /* FIXME I would like to do this after all set_property in a single
1264    * g_object_set () have been called. But an idle function won't
1265    * work; we need to emit when the tag is changed, not when we get
1266    * around to the event loop. So blah, we eat some inefficiency.
1267    */
1268
1269   /* This is also somewhat weird since we emit another object's
1270    * signal here, but the two objects are already tightly bound.
1271    */
1272
1273   if (text_tag->table)
1274     g_signal_emit_by_name (G_OBJECT (text_tag->table),
1275                            "tag_changed",
1276                            text_tag, size_changed);
1277 }
1278
1279 static void
1280 get_color_arg (GValue *value, GdkColor *orig)
1281 {
1282   GdkColor *color;
1283
1284   color = g_new (GdkColor, 1);
1285   *color = *orig;
1286   g_value_init (value, GDK_TYPE_COLOR);
1287   g_value_set_boxed (value, color);
1288 }
1289
1290 static void
1291 gtk_text_tag_get_property (GObject      *object,
1292                            guint         prop_id,
1293                            GValue       *value,
1294                            GParamSpec   *pspec)
1295 {
1296   GtkTextTag *tag;
1297
1298   tag = GTK_TEXT_TAG (object);
1299
1300   switch (prop_id)
1301     {
1302     case PROP_NAME:
1303       g_value_set_string (value, tag->name);
1304       break;
1305
1306     case PROP_BACKGROUND_GDK:
1307       get_color_arg (value, &tag->values->appearance.bg_color);
1308       break;
1309
1310     case PROP_FOREGROUND_GDK:
1311       get_color_arg (value, &tag->values->appearance.fg_color);
1312       break;
1313
1314     case PROP_BACKGROUND_STIPPLE:
1315       if (tag->bg_stipple_set)
1316         g_value_set_boxed (value, tag->values->appearance.bg_stipple);
1317       break;
1318
1319     case PROP_FOREGROUND_STIPPLE:
1320       if (tag->fg_stipple_set)
1321         g_value_set_boxed (value, tag->values->appearance.fg_stipple);
1322       break;
1323
1324     case PROP_FONT:
1325         {
1326           /* FIXME GValue imposes a totally gratuitous string copy
1327            * here, we could just hand off string ownership
1328            */
1329           gchar *str = pango_font_description_to_string (&tag->values->font);
1330           g_value_set_string (value, str);
1331           g_free (str);
1332         }
1333       break;
1334
1335     case PROP_FONT_DESC:
1336       g_value_set_boxed (value, &tag->values->font);
1337       break;
1338
1339     case PROP_FAMILY:
1340       g_value_set_string (value, tag->values->font.family_name);
1341       break;
1342
1343     case PROP_STYLE:
1344       g_value_set_enum (value, tag->values->font.style);
1345       break;
1346
1347     case PROP_VARIANT:
1348       g_value_set_enum (value, tag->values->font.variant);
1349       break;
1350
1351     case PROP_WEIGHT:
1352       g_value_set_int (value, tag->values->font.weight);
1353       break;
1354
1355     case PROP_STRETCH:
1356       g_value_set_enum (value, tag->values->font.stretch);
1357       break;
1358
1359     case PROP_SIZE:
1360       g_value_set_int (value,  tag->values->font.size);
1361       break;
1362       
1363     case PROP_SIZE_POINTS:
1364       g_value_set_double (value, ((double)tag->values->font.size) / (double)PANGO_SCALE);
1365       break;
1366
1367     case PROP_SCALE:
1368       g_value_set_double (value, tag->values->font_scale);
1369       break;
1370       
1371     case PROP_PIXELS_ABOVE_LINES:
1372       g_value_set_int (value,  tag->values->pixels_above_lines);
1373       break;
1374
1375     case PROP_PIXELS_BELOW_LINES:
1376       g_value_set_int (value,  tag->values->pixels_below_lines);
1377       break;
1378
1379     case PROP_PIXELS_INSIDE_WRAP:
1380       g_value_set_int (value,  tag->values->pixels_inside_wrap);
1381       break;
1382
1383     case PROP_EDITABLE:
1384       g_value_set_boolean (value, tag->values->editable);
1385       break;
1386
1387     case PROP_WRAP_MODE:
1388       g_value_set_enum (value, tag->values->wrap_mode);
1389       break;
1390
1391     case PROP_JUSTIFICATION:
1392       g_value_set_enum (value, tag->values->justification);
1393       break;
1394
1395     case PROP_DIRECTION:
1396       g_value_set_enum (value, tag->values->direction);
1397       break;
1398       
1399     case PROP_LEFT_MARGIN:
1400       g_value_set_int (value,  tag->values->left_margin);
1401       break;
1402
1403     case PROP_INDENT:
1404       g_value_set_int (value,  tag->values->indent);
1405       break;
1406
1407     case PROP_STRIKETHROUGH:
1408       g_value_set_boolean (value, tag->values->appearance.strikethrough);
1409       break;
1410
1411     case PROP_RIGHT_MARGIN:
1412       g_value_set_int (value, tag->values->right_margin);
1413       break;
1414
1415     case PROP_UNDERLINE:
1416       g_value_set_enum (value, tag->values->appearance.underline);
1417       break;
1418
1419     case PROP_RISE:
1420       g_value_set_int (value, tag->values->appearance.rise);
1421       break;
1422
1423     case PROP_BG_FULL_HEIGHT:
1424       g_value_set_boolean (value, tag->values->bg_full_height);
1425       break;
1426
1427     case PROP_LANGUAGE:
1428       g_value_set_string (value, tag->values->language);
1429       break;
1430
1431     case PROP_TABS:
1432       if (tag->values->tabs)
1433         g_value_set_boxed (value, tag->values->tabs);
1434       break;
1435
1436     case PROP_INVISIBLE:
1437       g_value_set_boolean (value, tag->values->invisible);
1438       break;
1439       
1440     case PROP_BACKGROUND_SET:
1441       g_value_set_boolean (value, tag->bg_color_set);
1442       break;
1443
1444     case PROP_FOREGROUND_SET:
1445       g_value_set_boolean (value, tag->fg_color_set);
1446       break;
1447
1448     case PROP_BACKGROUND_STIPPLE_SET:
1449       g_value_set_boolean (value, tag->bg_stipple_set);
1450       break;
1451
1452     case PROP_FOREGROUND_STIPPLE_SET:
1453       g_value_set_boolean (value, tag->fg_stipple_set);
1454       break;
1455
1456     case PROP_FAMILY_SET:
1457       g_value_set_boolean (value, tag->family_set);
1458       break;
1459
1460     case PROP_STYLE_SET:
1461       g_value_set_boolean (value, tag->style_set);
1462       break;
1463
1464     case PROP_VARIANT_SET:
1465       g_value_set_boolean (value, tag->variant_set);
1466       break;
1467
1468     case PROP_WEIGHT_SET:
1469       g_value_set_boolean (value, tag->weight_set);
1470       break;
1471
1472     case PROP_STRETCH_SET:
1473       g_value_set_boolean (value, tag->stretch_set);
1474       break;
1475
1476     case PROP_SIZE_SET:
1477       g_value_set_boolean (value, tag->size_set);
1478       break;
1479
1480     case PROP_SCALE_SET:
1481       g_value_set_boolean (value, tag->scale_set);
1482       break;
1483       
1484     case PROP_PIXELS_ABOVE_LINES_SET:
1485       g_value_set_boolean (value, tag->pixels_above_lines_set);
1486       break;
1487
1488     case PROP_PIXELS_BELOW_LINES_SET:
1489       g_value_set_boolean (value, tag->pixels_below_lines_set);
1490       break;
1491
1492     case PROP_PIXELS_INSIDE_WRAP_SET:
1493       g_value_set_boolean (value, tag->pixels_inside_wrap_set);
1494       break;
1495
1496     case PROP_EDITABLE_SET:
1497       g_value_set_boolean (value, tag->editable_set);
1498       break;
1499
1500     case PROP_WRAP_MODE_SET:
1501       g_value_set_boolean (value, tag->wrap_mode_set);
1502       break;
1503
1504     case PROP_JUSTIFICATION_SET:
1505       g_value_set_boolean (value, tag->justification_set);
1506       break;
1507       
1508     case PROP_LEFT_MARGIN_SET:
1509       g_value_set_boolean (value, tag->left_margin_set);
1510       break;
1511
1512     case PROP_INDENT_SET:
1513       g_value_set_boolean (value, tag->indent_set);
1514       break;
1515
1516     case PROP_STRIKETHROUGH_SET:
1517       g_value_set_boolean (value, tag->strikethrough_set);
1518       break;
1519
1520     case PROP_RIGHT_MARGIN_SET:
1521       g_value_set_boolean (value, tag->right_margin_set);
1522       break;
1523
1524     case PROP_UNDERLINE_SET:
1525       g_value_set_boolean (value, tag->underline_set);
1526       break;
1527
1528     case PROP_RISE_SET:
1529       g_value_set_boolean (value, tag->rise_set);
1530       break;
1531
1532     case PROP_BG_FULL_HEIGHT_SET:
1533       g_value_set_boolean (value, tag->bg_full_height_set);
1534       break;
1535
1536     case PROP_LANGUAGE_SET:
1537       g_value_set_boolean (value, tag->language_set);
1538       break;
1539
1540     case PROP_TABS_SET:
1541       g_value_set_boolean (value, tag->tabs_set);
1542       break;
1543
1544     case PROP_INVISIBLE_SET:
1545       g_value_set_boolean (value, tag->invisible_set);
1546       break;
1547       
1548     case PROP_BACKGROUND:
1549     case PROP_FOREGROUND:
1550       g_warning ("'foreground' and 'background' properties are not readable, use 'foreground_gdk' and 'background_gdk'");
1551     default:
1552       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1553       break;
1554     }
1555 }
1556
1557 /*
1558  * Tag operations
1559  */
1560
1561 typedef struct {
1562   gint high;
1563   gint low;
1564   gint delta;
1565 } DeltaData;
1566
1567 static void
1568 delta_priority_foreach (GtkTextTag *tag, gpointer user_data)
1569 {
1570   DeltaData *dd = user_data;
1571
1572   if (tag->priority >= dd->low && tag->priority <= dd->high)
1573     tag->priority += dd->delta;
1574 }
1575
1576 /**
1577  * gtk_text_tag_get_priority:
1578  * @tag: a #GtkTextTag
1579  * 
1580  * Get the tag priority.
1581  * 
1582  * Return value: The tag's priority.
1583  **/
1584 gint
1585 gtk_text_tag_get_priority (GtkTextTag *tag)
1586 {
1587   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), 0);
1588
1589   return tag->priority;
1590 }
1591
1592 /**
1593  * gtk_text_tag_set_priority:
1594  * @tag: a #GtkTextTag
1595  * @priority: the new priority
1596  * 
1597  * Sets the priority of a #GtkTextTag. Valid priorities are
1598  * start at 0 and go to one less than gtk_text_tag_table_size().
1599  * Each tag in a table has a unique priority; setting the priority
1600  * of one tag shifts the priorities of all the other tags in the
1601  * table to maintain a unique priority for each tag. Higher priority
1602  * tags "win" if two tags both set the same text attribute. When adding
1603  * a tag to a tag table, it will be assigned the highest priority in
1604  * the table by default; so normally the precedence of a set of tags
1605  * is the order in which they were added to the table, or created with
1606  * gtk_text_buffer_create_tag(), which adds the tag to the buffer's table
1607  * automatically.
1608  **/
1609 void
1610 gtk_text_tag_set_priority (GtkTextTag *tag,
1611                            gint        priority)
1612 {
1613   DeltaData dd;
1614
1615   g_return_if_fail (GTK_IS_TEXT_TAG (tag));
1616   g_return_if_fail (tag->table != NULL);
1617   g_return_if_fail (priority >= 0);
1618   g_return_if_fail (priority < gtk_text_tag_table_size (tag->table));
1619
1620   if (priority == tag->priority)
1621     return;
1622
1623   if (priority < tag->priority)
1624     {
1625       dd.low = priority;
1626       dd.high = tag->priority - 1;
1627       dd.delta = 1;
1628     }
1629   else
1630     {
1631       dd.low = tag->priority + 1;
1632       dd.high = priority;
1633       dd.delta = -1;
1634     }
1635
1636   gtk_text_tag_table_foreach (tag->table,
1637                               delta_priority_foreach,
1638                               &dd);
1639
1640   tag->priority = priority;
1641 }
1642
1643 /**
1644  * gtk_text_tag_event:
1645  * @tag: a #GtkTextTag
1646  * @event_object: object that received the event, such as a widget
1647  * @event: the event
1648  * @iter: location where the event was received
1649  * 
1650  * Emits the "event" signal on the #GtkTextTag.
1651  * 
1652  * Return value: result of signal emission (whether the event was handled)
1653  **/
1654 gboolean
1655 gtk_text_tag_event (GtkTextTag        *tag,
1656                     GObject           *event_object,
1657                     GdkEvent          *event,
1658                     const GtkTextIter *iter)
1659 {
1660   gboolean retval = FALSE;
1661
1662   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
1663   g_return_val_if_fail (GTK_IS_OBJECT (event_object), FALSE);
1664   g_return_val_if_fail (event != NULL, FALSE);
1665
1666   g_signal_emit (G_OBJECT (tag),
1667                  signals[EVENT],
1668                  0,
1669                  event_object,
1670                  event,
1671                  iter,
1672                  &retval);
1673
1674   return retval;
1675 }
1676
1677 static int
1678 tag_sort_func (gconstpointer first, gconstpointer second)
1679 {
1680   GtkTextTag *tag1, *tag2;
1681
1682   tag1 = * (GtkTextTag **) first;
1683   tag2 = * (GtkTextTag **) second;
1684   return tag1->priority - tag2->priority;
1685 }
1686
1687 void
1688 _gtk_text_tag_array_sort (GtkTextTag** tag_array_p,
1689                           guint len)
1690 {
1691   int i, j, prio;
1692   GtkTextTag **tag;
1693   GtkTextTag **maxPtrPtr, *tmp;
1694
1695   g_return_if_fail (tag_array_p != NULL);
1696   g_return_if_fail (len > 0);
1697
1698   if (len < 2) {
1699     return;
1700   }
1701   if (len < 20) {
1702     GtkTextTag **iter = tag_array_p;
1703
1704     for (i = len-1; i > 0; i--, iter++) {
1705       maxPtrPtr = tag = iter;
1706       prio = tag[0]->priority;
1707       for (j = i, tag++; j > 0; j--, tag++) {
1708         if (tag[0]->priority < prio) {
1709           prio = tag[0]->priority;
1710           maxPtrPtr = tag;
1711         }
1712       }
1713       tmp = *maxPtrPtr;
1714       *maxPtrPtr = *iter;
1715       *iter = tmp;
1716     }
1717   } else {
1718     qsort ((void *) tag_array_p, (unsigned) len, sizeof (GtkTextTag *),
1719            tag_sort_func);
1720   }
1721
1722 #if 0
1723   {
1724     printf ("Sorted tag array: \n");
1725     i = 0;
1726     while (i < len)
1727       {
1728         GtkTextTag *t = tag_array_p[i];
1729         printf ("  %s priority %d\n", t->name, t->priority);
1730
1731         ++i;
1732       }
1733   }
1734 #endif
1735 }
1736
1737 /*
1738  * Attributes
1739  */
1740
1741 /**
1742  * gtk_text_attributes_new:
1743  * 
1744  * Creates a #GtkTextAttributes, which describes
1745  * a set of properties on some text.
1746  * 
1747  * Return value: a new #GtkTextAttributes
1748  **/
1749 GtkTextAttributes*
1750 gtk_text_attributes_new (void)
1751 {
1752   GtkTextAttributes *values;
1753
1754   values = g_new0 (GtkTextAttributes, 1);
1755
1756   /* 0 is a valid value for most of the struct */
1757
1758   values->refcount = 1;
1759
1760   values->language = gtk_get_default_language ();
1761
1762   values->font_scale = 1.0;
1763   
1764   return values;
1765 }
1766
1767 /**
1768  * gtk_text_attributes_copy:
1769  * @src: a #GtkTextAttributes to be copied
1770  * 
1771  * Copies @src and returns a new #GtkTextAttributes.
1772  * 
1773  * Return value: a copy of @src
1774  **/
1775 GtkTextAttributes*
1776 gtk_text_attributes_copy (GtkTextAttributes *src)
1777 {
1778   GtkTextAttributes *dest;
1779
1780   dest = gtk_text_attributes_new ();
1781   gtk_text_attributes_copy_values (src, dest);
1782
1783   return dest;
1784 }
1785
1786 /**
1787  * gtk_text_attributes_copy_values:
1788  * @src: a #GtkTextAttributes
1789  * @dest: another #GtkTextAttributes
1790  * 
1791  * Copies the values from @src to @dest so that @dest has the same values
1792  * as @src. Frees existing values in @dest.
1793  **/
1794 void
1795 gtk_text_attributes_copy_values (GtkTextAttributes *src,
1796                                  GtkTextAttributes *dest)
1797 {
1798   guint orig_refcount;
1799
1800   g_return_if_fail (!dest->realized);
1801
1802   if (src == dest)
1803     return;
1804
1805   /* Add refs */
1806
1807   if (src->appearance.bg_stipple)
1808     gdk_bitmap_ref (src->appearance.bg_stipple);
1809
1810   if (src->appearance.fg_stipple)
1811     gdk_bitmap_ref (src->appearance.fg_stipple);
1812
1813   /* Remove refs */
1814
1815   if (dest->appearance.bg_stipple)
1816     gdk_bitmap_unref (dest->appearance.bg_stipple);
1817
1818   if (dest->appearance.fg_stipple)
1819     gdk_bitmap_unref (dest->appearance.fg_stipple);
1820
1821   if (dest->language)
1822     g_free (dest->language);
1823
1824   if (dest->font.family_name)
1825     g_free (dest->font.family_name);
1826   
1827   /* Copy */
1828   orig_refcount = dest->refcount;
1829
1830   *dest = *src;
1831
1832   if (src->tabs)
1833     dest->tabs = pango_tab_array_copy (src->tabs);
1834
1835   dest->language = g_strdup (src->language);
1836
1837   dest->font.family_name = g_strdup (src->font.family_name);
1838   
1839   dest->refcount = orig_refcount;
1840   dest->realized = FALSE;
1841 }
1842
1843 /**
1844  * gtk_text_attributes_ref:
1845  * @values: a #GtkTextAttributes
1846  * 
1847  * Increments the reference count on @values.
1848  **/
1849 void
1850 gtk_text_attributes_ref (GtkTextAttributes *values)
1851 {
1852   g_return_if_fail (values != NULL);
1853
1854   values->refcount += 1;
1855 }
1856
1857 /**
1858  * gtk_text_attributes_unref:
1859  * @values: a #GtkTextAttributes
1860  * 
1861  * Decrements the reference count on @values, freeing the structure
1862  * if the reference count reaches 0.
1863  **/
1864 void
1865 gtk_text_attributes_unref (GtkTextAttributes *values)
1866 {
1867   g_return_if_fail (values != NULL);
1868   g_return_if_fail (values->refcount > 0);
1869
1870   values->refcount -= 1;
1871
1872   if (values->refcount == 0)
1873     {
1874       g_assert (!values->realized);
1875
1876       if (values->appearance.bg_stipple)
1877         gdk_bitmap_unref (values->appearance.bg_stipple);
1878
1879       if (values->appearance.fg_stipple)
1880         gdk_bitmap_unref (values->appearance.fg_stipple);
1881
1882       if (values->tabs)
1883         pango_tab_array_free (values->tabs);
1884
1885       if (values->language)
1886         g_free (values->language);
1887
1888       if (values->font.family_name)
1889         g_free (values->font.family_name);
1890       
1891       g_free (values);
1892     }
1893 }
1894
1895 void
1896 _gtk_text_attributes_realize (GtkTextAttributes *values,
1897                               GdkColormap *cmap,
1898                               GdkVisual *visual)
1899 {
1900   g_return_if_fail (values != NULL);
1901   g_return_if_fail (values->refcount > 0);
1902   g_return_if_fail (!values->realized);
1903
1904   /* It is wrong to use this colormap, FIXME */
1905   gdk_colormap_alloc_color (cmap,
1906                             &values->appearance.fg_color,
1907                             FALSE, TRUE);
1908
1909   gdk_colormap_alloc_color (cmap,
1910                             &values->appearance.bg_color,
1911                             FALSE, TRUE);
1912
1913   values->realized = TRUE;
1914 }
1915
1916 void
1917 _gtk_text_attributes_unrealize (GtkTextAttributes *values,
1918                                 GdkColormap *cmap,
1919                                 GdkVisual *visual)
1920 {
1921   g_return_if_fail (values != NULL);
1922   g_return_if_fail (values->refcount > 0);
1923   g_return_if_fail (values->realized);
1924
1925   gdk_colormap_free_colors (cmap,
1926                             &values->appearance.fg_color, 1);
1927
1928
1929   gdk_colormap_free_colors (cmap,
1930                             &values->appearance.bg_color, 1);
1931
1932   values->appearance.fg_color.pixel = 0;
1933   values->appearance.bg_color.pixel = 0;
1934
1935   values->realized = FALSE;
1936 }
1937
1938 void
1939 _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
1940                                      GtkTextTag**       tags,
1941                                      guint              n_tags)
1942 {
1943   guint n = 0;
1944
1945   g_return_if_fail (!dest->realized);
1946
1947   while (n < n_tags)
1948     {
1949       GtkTextTag *tag = tags[n];
1950       GtkTextAttributes *vals = tag->values;
1951
1952       if (n > 0)
1953         g_assert (tags[n]->priority > tags[n-1]->priority);
1954
1955       if (tag->bg_color_set)
1956         {
1957           dest->appearance.bg_color = vals->appearance.bg_color;
1958
1959           dest->appearance.draw_bg = TRUE;
1960         }
1961       if (tag->fg_color_set)
1962         dest->appearance.fg_color = vals->appearance.fg_color;
1963       
1964       if (tag->bg_stipple_set)
1965         {
1966           gdk_bitmap_ref (vals->appearance.bg_stipple);
1967           if (dest->appearance.bg_stipple)
1968             gdk_bitmap_unref (dest->appearance.bg_stipple);
1969           dest->appearance.bg_stipple = vals->appearance.bg_stipple;
1970
1971           dest->appearance.draw_bg = TRUE;
1972         }
1973
1974       if (tag->fg_stipple_set)
1975         {
1976           gdk_bitmap_ref (vals->appearance.fg_stipple);
1977           if (dest->appearance.fg_stipple)
1978             gdk_bitmap_unref (dest->appearance.fg_stipple);
1979           dest->appearance.fg_stipple = vals->appearance.fg_stipple;
1980         }
1981
1982       if (tag->family_set)
1983         {
1984           if (dest->font.family_name)
1985             g_free (dest->font.family_name);
1986
1987           dest->font.family_name = g_strdup (vals->font.family_name);
1988         }
1989
1990       if (tag->style_set)
1991         dest->font.style = vals->font.style;
1992
1993       if (tag->variant_set)
1994         dest->font.variant = vals->font.variant;
1995
1996       if (tag->weight_set)
1997         dest->font.weight = vals->font.weight;
1998
1999       if (tag->stretch_set)
2000         dest->font.stretch = vals->font.stretch;
2001
2002       if (tag->size_set)
2003         dest->font.size = vals->font.size;
2004
2005       /* multiply all the scales together to get a composite */
2006       if (tag->scale_set)
2007         dest->font_scale *= vals->font_scale;
2008       
2009       if (tag->justification_set)
2010         dest->justification = vals->justification;
2011
2012       if (vals->direction != GTK_TEXT_DIR_NONE)
2013         dest->direction = vals->direction;
2014
2015       if (tag->left_margin_set)
2016         dest->left_margin = vals->left_margin;
2017
2018       if (tag->indent_set)
2019         dest->indent = vals->indent;
2020
2021       if (tag->rise_set)
2022         dest->appearance.rise = vals->appearance.rise;
2023
2024       if (tag->right_margin_set)
2025         dest->right_margin = vals->right_margin;
2026
2027       if (tag->pixels_above_lines_set)
2028         dest->pixels_above_lines = vals->pixels_above_lines;
2029
2030       if (tag->pixels_below_lines_set)
2031         dest->pixels_below_lines = vals->pixels_below_lines;
2032
2033       if (tag->pixels_inside_wrap_set)
2034         dest->pixels_inside_wrap = vals->pixels_inside_wrap;
2035
2036       if (tag->tabs_set)
2037         {
2038           if (dest->tabs)
2039             pango_tab_array_free (dest->tabs);
2040           dest->tabs = pango_tab_array_copy (vals->tabs);
2041         }
2042
2043       if (tag->wrap_mode_set)
2044         dest->wrap_mode = vals->wrap_mode;
2045
2046       if (tag->underline_set)
2047         dest->appearance.underline = vals->appearance.underline;
2048
2049       if (tag->strikethrough_set)
2050         dest->appearance.strikethrough = vals->appearance.strikethrough;
2051
2052       if (tag->invisible_set)
2053         dest->invisible = vals->invisible;
2054
2055       if (tag->editable_set)
2056         dest->editable = vals->editable;
2057
2058       if (tag->bg_full_height_set)
2059         dest->bg_full_height = vals->bg_full_height;
2060
2061       if (tag->language_set)
2062         {
2063           g_free (dest->language);
2064           dest->language = g_strdup (vals->language);
2065         }
2066
2067       ++n;
2068     }
2069 }
2070
2071 gboolean
2072 _gtk_text_tag_affects_size (GtkTextTag *tag)
2073 {
2074   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
2075
2076   return
2077     tag->family_set ||
2078     tag->style_set ||
2079     tag->variant_set ||
2080     tag->weight_set ||
2081     tag->size_set ||
2082     tag->scale_set ||
2083     tag->stretch_set ||
2084     tag->justification_set ||
2085     tag->left_margin_set ||
2086     tag->indent_set ||
2087     tag->rise_set ||
2088     tag->right_margin_set ||
2089     tag->pixels_above_lines_set ||
2090     tag->pixels_below_lines_set ||
2091     tag->pixels_inside_wrap_set ||
2092     tag->tabs_set ||
2093     tag->underline_set ||
2094     tag->wrap_mode_set ||
2095     tag->invisible_set;
2096 }
2097
2098 gboolean
2099 _gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag)
2100 {
2101   g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
2102
2103   return
2104     tag->bg_color_set ||
2105     tag->bg_stipple_set ||
2106     tag->fg_color_set ||
2107     tag->fg_stipple_set ||
2108     tag->strikethrough_set ||
2109     tag->bg_full_height_set;
2110 }