diff --git a/gtk/gtktextattributes.c b/gtk/gtktextattributes.c index dc1360caf5..21a9d05609 100644 --- a/gtk/gtktextattributes.c +++ b/gtk/gtktextattributes.c @@ -143,6 +143,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS if (dest->appearance.rgba[1]) gdk_rgba_free (dest->appearance.rgba[1]); + if (dest->font_features) + g_free (dest->font_features); + /* Copy */ orig_refcount = dest->refcount; @@ -170,13 +173,16 @@ G_GNUC_END_IGNORE_DEPRECATIONS if (src->appearance.rgba[1]) dest->appearance.rgba[1] = gdk_rgba_copy (src->appearance.rgba[1]); + if (src->font_features) + dest->font_features = g_strdup (src->font_features); + dest->refcount = orig_refcount; } /** * gtk_text_attributes_ref: * @values: a #GtkTextAttributes - * + * * Increments the reference count on @values. * * Returns: the #GtkTextAttributes that were passed in @@ -228,6 +234,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS if (values->appearance.rgba[1]) gdk_rgba_free (values->appearance.rgba[1]); + if (values->font_features) + g_free (values->font_features); + g_slice_free (GtkTextAttributes, values); } } @@ -403,6 +412,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS if (tag->priv->letter_spacing_set) dest->letter_spacing = vals->letter_spacing; + if (tag->priv->font_features_set) + dest->font_features = g_strdup (vals->font_features); + ++n; } @@ -430,6 +442,7 @@ _gtk_text_tag_affects_size (GtkTextTag *tag) priv->underline_set || priv->wrap_mode_set || priv->invisible_set || + priv->font_features_set || priv->letter_spacing_set; } diff --git a/gtk/gtktextattributes.h b/gtk/gtktextattributes.h index 83a6312bd4..77c70f1a63 100644 --- a/gtk/gtktextattributes.h +++ b/gtk/gtktextattributes.h @@ -207,8 +207,23 @@ struct _GtkTextAttributes /*< public >*/ gint letter_spacing; +#ifdef __GI_SCANNER__ + /* The scanner should only see the transparent union, so that its + * content does not vary across architectures. + */ + union { + gchar *font_features; + /*< private >*/ + guint padding[2]; + }; +#else + gchar *font_features; +#if (defined(__SIZEOF_INT__) && defined(__SIZEOF_POINTER__)) && (__SIZEOF_INT__ == __SIZEOF_POINTER__) + /* unusable, just for ABI compat */ /*< private >*/ - guint padding[2]; + guint padding[1]; +#endif +#endif }; GDK_AVAILABLE_IN_ALL diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index 5bb9a210b8..8e3e1de04e 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -4837,6 +4837,10 @@ get_tag_for_attributes (PangoAttrIterator *iter) if (attr) g_object_set (tag, "letter-spacing", ((PangoAttrInt*)attr)->value, NULL); + attr = pango_attr_iterator_get (iter, PANGO_ATTR_FONT_FEATURES); + if (attr) + g_object_set (tag, "font-features", ((PangoAttrString*)attr)->value, NULL); + return tag; } diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 763ef3b7c8..041f062f11 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -1639,10 +1639,9 @@ add_text_attrs (GtkTextLayout *layout, if (style->font_scale != 1.0) { attr = pango_attr_scale_new (style->font_scale); - attr->start_index = start; attr->end_index = start + byte_count; - + pango_attr_list_insert (attrs, attr); } @@ -1661,6 +1660,15 @@ add_text_attrs (GtkTextLayout *layout, attr->start_index = start; attr->end_index = start + byte_count; + pango_attr_list_insert (attrs, attr); + } + + if (style->font_features) + { + attr = pango_attr_font_features_new (style->font_features); + attr->start_index = start; + attr->end_index = start + byte_count; + pango_attr_list_insert (attrs, attr); } } diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c index 58ab9fa971..9a11050ca6 100644 --- a/gtk/gtktexttag.c +++ b/gtk/gtktexttag.c @@ -134,10 +134,11 @@ enum { PROP_PARAGRAPH_BACKGROUND_RGBA, PROP_FALLBACK, PROP_LETTER_SPACING, + PROP_FONT_FEATURES, /* Behavior args */ PROP_ACCUMULATIVE_MARGIN, - + /* Whether-a-style-arg-is-set args */ PROP_BACKGROUND_SET, PROP_FOREGROUND_SET, @@ -169,6 +170,7 @@ enum { PROP_PARAGRAPH_BACKGROUND_SET, PROP_FALLBACK_SET, PROP_LETTER_SPACING_SET, + PROP_FONT_FEATURES_SET, LAST_ARG }; @@ -676,6 +678,22 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) P_("Extra spacing between graphemes"), 0, G_MAXINT, 0, GTK_PARAM_READWRITE)); + + /** + * GtkTextTag:font-features: + * + * OpenType font features, as a string. + * + * Since: 3.18 + */ + g_object_class_install_property (object_class, + PROP_FONT_FEATURES, + g_param_spec_string ("font-features", + P_("Font Features"), + P_("OpenType Font Features to use"), + NULL, + GTK_PARAM_READWRITE)); + /** * GtkTextTag:accumulative-margin: * @@ -833,6 +851,10 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) P_("Letter spacing set"), P_("Whether this tag affects letter spacing")); + ADD_SET_PROP ("font-features-set", PROP_FONT_FEATURES_SET, + P_("Font features set"), + P_("Whether this tag affects font features")); + /** * GtkTextTag::event: * @tag: the #GtkTextTag on which the signal is emitted @@ -1643,6 +1665,12 @@ gtk_text_tag_set_property (GObject *object, g_object_notify (object, "letter-spacing-set"); break; + case PROP_FONT_FEATURES: + priv->font_features_set = TRUE; + priv->values->font_features = g_value_dup_string (value); + g_object_notify (object, "font-features-set"); + break; + case PROP_ACCUMULATIVE_MARGIN: priv->accumulative_margin = g_value_get_boolean (value); g_object_notify (object, "accumulative-margin"); @@ -1785,6 +1813,10 @@ gtk_text_tag_set_property (GObject *object, priv->letter_spacing_set = g_value_get_boolean (value); break; + case PROP_FONT_FEATURES_SET: + priv->font_features_set = g_value_get_boolean (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2002,6 +2034,10 @@ gtk_text_tag_get_property (GObject *object, g_value_set_int (value, priv->values->letter_spacing); break; + case PROP_FONT_FEATURES: + g_value_set_string (value, priv->values->font_features); + break; + case PROP_ACCUMULATIVE_MARGIN: g_value_set_boolean (value, priv->accumulative_margin); break; @@ -2118,6 +2154,10 @@ gtk_text_tag_get_property (GObject *object, g_value_set_boolean (value, priv->letter_spacing_set); break; + case PROP_FONT_FEATURES_SET: + g_value_set_boolean (value, priv->font_features_set); + break; + case PROP_BACKGROUND: case PROP_FOREGROUND: case PROP_PARAGRAPH_BACKGROUND: diff --git a/gtk/gtktexttagprivate.h b/gtk/gtktexttagprivate.h index cd31b7cb2c..26f30263d6 100644 --- a/gtk/gtktexttagprivate.h +++ b/gtk/gtktexttagprivate.h @@ -77,6 +77,7 @@ struct _GtkTextTagPrivate guint pg_bg_color_set : 1; guint fallback_set : 1; guint letter_spacing_set : 1; + guint font_features_set : 1; /* Whether these margins accumulate or override */ guint accumulative_margin : 1;