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