X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktexttag.c;h=8674e92c9f0cd74a2be7f9a049c56bfc5dd3e026;hb=bb3c56abe2e7916126bd4f8234dee080b5381941;hp=cb62ebfa5c67a3143a4fe6bf204feaf11268f645;hpb=55016f72f2fe91f088f5d2c12b1c5c38e42f8f3a;p=~andy%2Fgtk diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c index cb62ebfa5..8674e92c9 100644 --- a/gtk/gtktexttag.c +++ b/gtk/gtktexttag.c @@ -47,17 +47,39 @@ * */ +/** + * SECTION:gtktexttag + * @Title: GtkTextTag + * @Short_description: A tag that can be applied to text in a GtkTextBuffer + * + * You may wish to begin by reading the text widget + * conceptual overview which gives an overview of all the objects and + * data types related to the text widget and how they work together. + * + * Tags should be in the #GtkTextTagTable for a given #GtkTextBuffer + * before using them with that buffer. + * + * gtk_text_buffer_create_tag() is the best way to create tags. + * See gtk3-demo for numerous examples. + * + * For each property of #GtkTextTag, there is a "set" property, e.g. + * "font-set" corresponds to "font". These "set" properties reflect + * whether a property has been set or not. + * They are maintained by GTK+ and you should not set them independently. + */ + #include "config.h" -#include "gtkmain.h" + +#include +#include + #include "gtktexttag.h" #include "gtktexttypes.h" #include "gtktexttagtable.h" #include "gtkintl.h" #include "gtkmarshalers.h" #include "gtkprivate.h" - -#include -#include +#include "gtktypebuiltins.h" enum { EVENT, @@ -74,6 +96,8 @@ enum { PROP_FOREGROUND, PROP_BACKGROUND_GDK, PROP_FOREGROUND_GDK, + PROP_BACKGROUND_RGBA, + PROP_FOREGROUND_RGBA, PROP_FONT, PROP_FONT_DESC, PROP_FAMILY, @@ -103,6 +127,7 @@ enum { PROP_INVISIBLE, PROP_PARAGRAPH_BACKGROUND, PROP_PARAGRAPH_BACKGROUND_GDK, + PROP_PARAGRAPH_BACKGROUND_RGBA, /* Behavior args */ PROP_ACCUMULATIVE_MARGIN, @@ -180,12 +205,34 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) NULL, GTK_PARAM_WRITABLE)); + /** + * GtkTextTag:background-gdk: + * + * Background color as a #GdkColor. + * + * Deprecated: 3.4: Use #GtkTextTag:background-rgba instead. + */ g_object_class_install_property (object_class, PROP_BACKGROUND_GDK, g_param_spec_boxed ("background-gdk", P_("Background color"), - P_("Background color as a (possibly unallocated) GdkColor"), + P_("Background color as a GdkColor"), GDK_TYPE_COLOR, + GTK_PARAM_READWRITE | G_PARAM_DEPRECATED)); + + /** + * GtkTextTag:background-rgba: + * + * Background color as a #GdkRGBA. + * + * Since: 3.2 + */ + g_object_class_install_property (object_class, + PROP_BACKGROUND_RGBA, + g_param_spec_boxed ("background-rgba", + P_("Background RGBA"), + P_("Background color as a GdkRGBA"), + GDK_TYPE_RGBA, GTK_PARAM_READWRITE)); g_object_class_install_property (object_class, @@ -204,12 +251,34 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) NULL, GTK_PARAM_WRITABLE)); + /** + * GtkTextTag:foreground-gdk: + * + * Foreground color as a #GdkColor. + * + * Deprecated: 3.4: Use #GtkTextTag:foreground-rgba instead. + */ g_object_class_install_property (object_class, PROP_FOREGROUND_GDK, g_param_spec_boxed ("foreground-gdk", P_("Foreground color"), - P_("Foreground color as a (possibly unallocated) GdkColor"), + P_("Foreground color as a GdkColor"), GDK_TYPE_COLOR, + GTK_PARAM_READWRITE | G_PARAM_DEPRECATED)); + + /** + * GtkTextTag:foreground-rgba: + * + * Foreground color as a #GdkRGBA. + * + * Since: 3.2 + */ + g_object_class_install_property (object_class, + PROP_FOREGROUND_RGBA, + g_param_spec_boxed ("foreground-rgba", + P_("Foreground RGBA"), + P_("Foreground color as a GdkRGBA"), + GDK_TYPE_RGBA, GTK_PARAM_READWRITE)); g_object_class_install_property (object_class, @@ -500,17 +569,33 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) /** * GtkTextTag:paragraph-background-gdk: * - * The paragraph background color as a as a (possibly unallocated) - * #GdkColor. + * The paragraph background color as a as a #GdkColor. * * Since: 2.8 + * + * Deprecated: 3.4: Use #GtkTextTag:paragraph-background-rgba instead. */ g_object_class_install_property (object_class, PROP_PARAGRAPH_BACKGROUND_GDK, g_param_spec_boxed ("paragraph-background-gdk", P_("Paragraph background color"), - P_("Paragraph background color as a (possibly unallocated) GdkColor"), + P_("Paragraph background color as a GdkColor"), GDK_TYPE_COLOR, + GTK_PARAM_READWRITE | G_PARAM_DEPRECATED)); + + /** + * GtkTextTag:paragraph-background-rgba: + * + * The paragraph background color as a as a #GdkRGBA. + * + * Since: 3.2 + */ + g_object_class_install_property (object_class, + PROP_PARAGRAPH_BACKGROUND_RGBA, + g_param_spec_boxed ("paragraph-background-rgba", + P_("Paragraph background RGBA"), + P_("Paragraph background RGBA as a GdkRGBA"), + GDK_TYPE_RGBA, GTK_PARAM_READWRITE)); /** @@ -722,11 +807,35 @@ gtk_text_tag_finalize (GObject *object) } static void -set_bg_color (GtkTextTag *tag, GdkColor *color) +copy_rgba_to_gdk_color (GdkRGBA *src, + GdkColor *dest) +{ + dest->red = CLAMP (src->red, 0.0, 1.0) * 65535.0; + dest->green = CLAMP (src->green, 0.0, 1.0) * 65535.0; + dest->blue = CLAMP (src->blue, 0.0, 1.0) * 65535.0; +} + +static void +copy_gdk_color_to_rgba (GdkColor *src, + GdkRGBA *dest) +{ + dest->red = src->red / 65535.; + dest->green = src->green / 65535.; + dest->blue = src->blue / 65535.; + dest->alpha = 1; +} + +static void +set_bg_rgba (GtkTextTag *tag, GdkRGBA *rgba) { GtkTextTagPrivate *priv = tag->priv; - if (color) + if (priv->values->appearance.rgba[0]) + gdk_rgba_free (priv->values->appearance.rgba[0]); + + priv->values->appearance.rgba[0] = NULL; + + if (rgba) { if (!priv->bg_color_set) { @@ -734,7 +843,9 @@ set_bg_color (GtkTextTag *tag, GdkColor *color) g_object_notify (G_OBJECT (tag), "background-set"); } - priv->values->appearance.bg_color = *color; + priv->values->appearance.rgba[0] = gdk_rgba_copy (rgba); + + copy_rgba_to_gdk_color (rgba, &priv->values->appearance.bg_color); } else { @@ -747,18 +858,26 @@ set_bg_color (GtkTextTag *tag, GdkColor *color) } static void -set_fg_color (GtkTextTag *tag, GdkColor *color) +set_fg_rgba (GtkTextTag *tag, GdkRGBA *rgba) { GtkTextTagPrivate *priv = tag->priv; - if (color) + if (priv->values->appearance.rgba[1]) + gdk_rgba_free (priv->values->appearance.rgba[1]); + + priv->values->appearance.rgba[1] = NULL; + + if (rgba) { if (!priv->fg_color_set) { priv->fg_color_set = TRUE; g_object_notify (G_OBJECT (tag), "foreground-set"); } - priv->values->appearance.fg_color = *color; + + priv->values->appearance.rgba[1] = gdk_rgba_copy (rgba); + + copy_rgba_to_gdk_color (rgba, &priv->values->appearance.fg_color); } else { @@ -771,21 +890,33 @@ set_fg_color (GtkTextTag *tag, GdkColor *color) } static void -set_pg_bg_color (GtkTextTag *tag, GdkColor *color) +set_pg_bg_rgba (GtkTextTag *tag, GdkRGBA *rgba) { GtkTextTagPrivate *priv = tag->priv; - if (color) + if (priv->values->pg_bg_rgba) + gdk_rgba_free (priv->values->pg_bg_rgba); + + if (priv->values->pg_bg_color) + gdk_color_free (priv->values->pg_bg_color); + + priv->values->pg_bg_rgba = NULL; + priv->values->pg_bg_color = NULL; + + if (rgba) { + GdkColor color = { 0, }; + if (!priv->pg_bg_color_set) { priv->pg_bg_color_set = TRUE; g_object_notify (G_OBJECT (tag), "paragraph-background-set"); } - else - gdk_color_free (priv->values->pg_bg_color); - priv->values->pg_bg_color = gdk_color_copy (color); + priv->values->pg_bg_rgba = gdk_rgba_copy (rgba); + + copy_rgba_to_gdk_color (rgba, &color); + priv->values->pg_bg_color = gdk_color_copy (&color); } else { @@ -793,11 +924,51 @@ set_pg_bg_color (GtkTextTag *tag, GdkColor *color) { priv->pg_bg_color_set = FALSE; g_object_notify (G_OBJECT (tag), "paragraph-background-set"); - gdk_color_free (priv->values->pg_bg_color); } + } +} + + +static void +set_bg_color (GtkTextTag *tag, GdkColor *color) +{ + if (color) + { + GdkRGBA rgba; - priv->values->pg_bg_color = NULL; + copy_gdk_color_to_rgba (color, &rgba); + set_bg_rgba (tag, &rgba); } + else + set_bg_rgba (tag, NULL); +} + +static void +set_fg_color (GtkTextTag *tag, GdkColor *color) +{ + if (color) + { + GdkRGBA rgba; + + copy_gdk_color_to_rgba (color, &rgba); + set_fg_rgba (tag, &rgba); + } + else + set_fg_rgba (tag, NULL); +} + +static void +set_pg_bg_color (GtkTextTag *tag, GdkColor *color) +{ + if (color) + { + GdkRGBA rgba; + + copy_gdk_color_to_rgba (color, &rgba); + set_pg_bg_rgba (tag, &rgba); + } + else + set_pg_bg_rgba (tag, NULL); } static PangoFontMask @@ -980,12 +1151,12 @@ gtk_text_tag_set_property (GObject *object, case PROP_BACKGROUND: { - GdkColor color; + GdkRGBA rgba; if (!g_value_get_string (value)) - set_bg_color (text_tag, NULL); /* reset to background_set to FALSE */ - else if (gdk_color_parse (g_value_get_string (value), &color)) - set_bg_color (text_tag, &color); + set_bg_rgba (text_tag, NULL); /* reset background_set to FALSE */ + else if (gdk_rgba_parse (&rgba, g_value_get_string (value))) + set_bg_rgba (text_tag, &rgba); else g_warning ("Don't know color `%s'", g_value_get_string (value)); @@ -995,12 +1166,12 @@ gtk_text_tag_set_property (GObject *object, case PROP_FOREGROUND: { - GdkColor color; + GdkRGBA rgba; if (!g_value_get_string (value)) - set_fg_color (text_tag, NULL); /* reset to foreground_set to FALSE */ - else if (gdk_color_parse (g_value_get_string (value), &color)) - set_fg_color (text_tag, &color); + set_fg_rgba (text_tag, NULL); /* reset to foreground_set to FALSE */ + else if (gdk_rgba_parse (&rgba, g_value_get_string (value))) + set_fg_rgba (text_tag, &rgba); else g_warning ("Don't know color `%s'", g_value_get_string (value)); @@ -1024,6 +1195,22 @@ gtk_text_tag_set_property (GObject *object, } break; + case PROP_BACKGROUND_RGBA: + { + GdkRGBA *color = g_value_get_boxed (value); + + set_bg_rgba (text_tag, color); + } + break; + + case PROP_FOREGROUND_RGBA: + { + GdkRGBA *color = g_value_get_boxed (value); + + set_fg_rgba (text_tag, color); + } + break; + case PROP_FONT: { PangoFontDescription *font_desc = NULL; @@ -1237,12 +1424,12 @@ gtk_text_tag_set_property (GObject *object, case PROP_PARAGRAPH_BACKGROUND: { - GdkColor color; + GdkRGBA rgba; if (!g_value_get_string (value)) - set_pg_bg_color (text_tag, NULL); /* reset to paragraph_background_set to FALSE */ - else if (gdk_color_parse (g_value_get_string (value), &color)) - set_pg_bg_color (text_tag, &color); + set_pg_bg_rgba (text_tag, NULL); /* reset paragraph_background_set to FALSE */ + else if (gdk_rgba_parse (&rgba, g_value_get_string (value))) + set_pg_bg_rgba (text_tag, &rgba); else g_warning ("Don't know color `%s'", g_value_get_string (value)); @@ -1258,6 +1445,14 @@ gtk_text_tag_set_property (GObject *object, } break; + case PROP_PARAGRAPH_BACKGROUND_RGBA: + { + GdkRGBA *color = g_value_get_boxed (value); + + set_pg_bg_rgba (text_tag, color); + } + break; + case PROP_ACCUMULATIVE_MARGIN: priv->accumulative_margin = g_value_get_boolean (value); g_object_notify (object, "accumulative-margin"); @@ -1422,10 +1617,18 @@ gtk_text_tag_get_property (GObject *object, g_value_set_boxed (value, &priv->values->appearance.bg_color); break; + case PROP_BACKGROUND_RGBA: + g_value_set_boxed (value, priv->values->appearance.rgba[0]); + break; + case PROP_FOREGROUND_GDK: g_value_set_boxed (value, &priv->values->appearance.fg_color); break; + case PROP_FOREGROUND_RGBA: + g_value_set_boxed (value, priv->values->appearance.rgba[1]); + break; + case PROP_FONT: { gchar *str; @@ -1559,6 +1762,10 @@ gtk_text_tag_get_property (GObject *object, g_value_set_boxed (value, priv->values->pg_bg_color); break; + case PROP_PARAGRAPH_BACKGROUND_RGBA: + g_value_set_boxed (value, priv->values->pg_bg_rgba); + break; + case PROP_ACCUMULATIVE_MARGIN: g_value_set_boolean (value, priv->accumulative_margin); break; @@ -1661,6 +1868,7 @@ gtk_text_tag_get_property (GObject *object, case PROP_FOREGROUND: case PROP_PARAGRAPH_BACKGROUND: g_warning ("'foreground', 'background' and 'paragraph_background' properties are not readable, use 'foreground_gdk', 'background_gdk' and 'paragraph_background_gdk'"); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1852,298 +2060,3 @@ _gtk_text_tag_array_sort (GtkTextTag** tag_array_p, #endif } -/* - * Attributes - */ - -/** - * gtk_text_attributes_new: - * - * Creates a #GtkTextAttributes, which describes - * a set of properties on some text. - * - * Return value: a new #GtkTextAttributes - **/ -GtkTextAttributes* -gtk_text_attributes_new (void) -{ - GtkTextAttributes *values; - - values = g_new0 (GtkTextAttributes, 1); - - /* 0 is a valid value for most of the struct */ - - values->refcount = 1; - - values->language = gtk_get_default_language (); - - values->font_scale = 1.0; - - values->editable = TRUE; - - return values; -} - -/** - * gtk_text_attributes_copy: - * @src: a #GtkTextAttributes to be copied - * - * Copies @src and returns a new #GtkTextAttributes. - * - * Return value: a copy of @src - **/ -GtkTextAttributes* -gtk_text_attributes_copy (GtkTextAttributes *src) -{ - GtkTextAttributes *dest; - - dest = gtk_text_attributes_new (); - gtk_text_attributes_copy_values (src, dest); - - return dest; -} - -G_DEFINE_BOXED_TYPE (GtkTextAttributes, gtk_text_attributes, - gtk_text_attributes_ref, - gtk_text_attributes_unref) - -/** - * gtk_text_attributes_copy_values: - * @src: a #GtkTextAttributes - * @dest: another #GtkTextAttributes - * - * Copies the values from @src to @dest so that @dest has the same values - * as @src. Frees existing values in @dest. - **/ -void -gtk_text_attributes_copy_values (GtkTextAttributes *src, - GtkTextAttributes *dest) -{ - guint orig_refcount; - - if (src == dest) - return; - - /* Remove refs */ - - if (dest->font) - pango_font_description_free (dest->font); - - /* Copy */ - orig_refcount = dest->refcount; - - *dest = *src; - - if (src->tabs) - dest->tabs = pango_tab_array_copy (src->tabs); - - dest->language = src->language; - - if (dest->font) - dest->font = pango_font_description_copy (src->font); - - if (src->pg_bg_color) - dest->pg_bg_color = gdk_color_copy (src->pg_bg_color); - - dest->refcount = orig_refcount; -} - -/** - * gtk_text_attributes_ref: - * @values: a #GtkTextAttributes - * - * Increments the reference count on @values. - * - * Returns: the #GtkTextAttributes that were passed in - **/ -GtkTextAttributes * -gtk_text_attributes_ref (GtkTextAttributes *values) -{ - g_return_val_if_fail (values != NULL, NULL); - - values->refcount += 1; - - return values; -} - -/** - * gtk_text_attributes_unref: - * @values: a #GtkTextAttributes - * - * Decrements the reference count on @values, freeing the structure - * if the reference count reaches 0. - **/ -void -gtk_text_attributes_unref (GtkTextAttributes *values) -{ - g_return_if_fail (values != NULL); - g_return_if_fail (values->refcount > 0); - - values->refcount -= 1; - - if (values->refcount == 0) - { - if (values->tabs) - pango_tab_array_free (values->tabs); - - if (values->font) - pango_font_description_free (values->font); - - if (values->pg_bg_color) - gdk_color_free (values->pg_bg_color); - - g_free (values); - } -} - -void -_gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest, - GtkTextTag** tags, - guint n_tags) -{ - guint n = 0; - - guint left_margin_accumulative = 0; - guint right_margin_accumulative = 0; - - while (n < n_tags) - { - GtkTextTag *tag = tags[n]; - GtkTextAttributes *vals = tag->priv->values; - - g_assert (tag->priv->table != NULL); - if (n > 0) - g_assert (tags[n]->priv->priority > tags[n-1]->priv->priority); - - if (tag->priv->bg_color_set) - { - dest->appearance.bg_color = vals->appearance.bg_color; - - dest->appearance.draw_bg = TRUE; - } - if (tag->priv->fg_color_set) - dest->appearance.fg_color = vals->appearance.fg_color; - - if (tag->priv->pg_bg_color_set) - { - dest->pg_bg_color = gdk_color_copy (vals->pg_bg_color); - } - - if (vals->font) - { - if (dest->font) - pango_font_description_merge (dest->font, vals->font, TRUE); - else - dest->font = pango_font_description_copy (vals->font); - } - - /* multiply all the scales together to get a composite */ - if (tag->priv->scale_set) - dest->font_scale *= vals->font_scale; - - if (tag->priv->justification_set) - dest->justification = vals->justification; - - if (vals->direction != GTK_TEXT_DIR_NONE) - dest->direction = vals->direction; - - if (tag->priv->left_margin_set) - { - if (tag->priv->accumulative_margin) - left_margin_accumulative += vals->left_margin; - else - dest->left_margin = vals->left_margin; - } - - if (tag->priv->indent_set) - dest->indent = vals->indent; - - if (tag->priv->rise_set) - dest->appearance.rise = vals->appearance.rise; - - if (tag->priv->right_margin_set) - { - if (tag->priv->accumulative_margin) - right_margin_accumulative += vals->right_margin; - else - dest->right_margin = vals->right_margin; - } - - if (tag->priv->pixels_above_lines_set) - dest->pixels_above_lines = vals->pixels_above_lines; - - if (tag->priv->pixels_below_lines_set) - dest->pixels_below_lines = vals->pixels_below_lines; - - if (tag->priv->pixels_inside_wrap_set) - dest->pixels_inside_wrap = vals->pixels_inside_wrap; - - if (tag->priv->tabs_set) - { - if (dest->tabs) - pango_tab_array_free (dest->tabs); - dest->tabs = pango_tab_array_copy (vals->tabs); - } - - if (tag->priv->wrap_mode_set) - dest->wrap_mode = vals->wrap_mode; - - if (tag->priv->underline_set) - dest->appearance.underline = vals->appearance.underline; - - if (tag->priv->strikethrough_set) - dest->appearance.strikethrough = vals->appearance.strikethrough; - - if (tag->priv->invisible_set) - dest->invisible = vals->invisible; - - if (tag->priv->editable_set) - dest->editable = vals->editable; - - if (tag->priv->bg_full_height_set) - dest->bg_full_height = vals->bg_full_height; - - if (tag->priv->language_set) - dest->language = vals->language; - - ++n; - } - - dest->left_margin += left_margin_accumulative; - dest->right_margin += right_margin_accumulative; -} - -gboolean -_gtk_text_tag_affects_size (GtkTextTag *tag) -{ - GtkTextTagPrivate *priv = tag->priv; - - return - (priv->values->font && pango_font_description_get_set_fields (priv->values->font) != 0) || - priv->scale_set || - priv->justification_set || - priv->left_margin_set || - priv->indent_set || - priv->rise_set || - priv->right_margin_set || - priv->pixels_above_lines_set || - priv->pixels_below_lines_set || - priv->pixels_inside_wrap_set || - priv->tabs_set || - priv->underline_set || - priv->wrap_mode_set || - priv->invisible_set; -} - -gboolean -_gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag) -{ - GtkTextTagPrivate *priv = tag->priv; - - return - priv->bg_color_set || - priv->fg_color_set || - priv->strikethrough_set || - priv->bg_full_height_set || - priv->pg_bg_color_set; -}