GtkTextView: Support font features

Add a ::font-features attribute to GtkTextTag, and support
font features when inserting Pango markup into a text buffer.
This commit is contained in:
Matthias Clasen 2015-07-29 18:28:56 -04:00
parent 98f9532a22
commit c6838fbff0
6 changed files with 86 additions and 5 deletions

View File

@ -143,6 +143,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
if (dest->appearance.rgba[1]) if (dest->appearance.rgba[1])
gdk_rgba_free (dest->appearance.rgba[1]); gdk_rgba_free (dest->appearance.rgba[1]);
if (dest->font_features)
g_free (dest->font_features);
/* Copy */ /* Copy */
orig_refcount = dest->refcount; orig_refcount = dest->refcount;
@ -170,13 +173,16 @@ G_GNUC_END_IGNORE_DEPRECATIONS
if (src->appearance.rgba[1]) if (src->appearance.rgba[1])
dest->appearance.rgba[1] = gdk_rgba_copy (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; dest->refcount = orig_refcount;
} }
/** /**
* gtk_text_attributes_ref: * gtk_text_attributes_ref:
* @values: a #GtkTextAttributes * @values: a #GtkTextAttributes
* *
* Increments the reference count on @values. * Increments the reference count on @values.
* *
* Returns: the #GtkTextAttributes that were passed in * Returns: the #GtkTextAttributes that were passed in
@ -228,6 +234,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
if (values->appearance.rgba[1]) if (values->appearance.rgba[1])
gdk_rgba_free (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); g_slice_free (GtkTextAttributes, values);
} }
} }
@ -403,6 +412,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
if (tag->priv->letter_spacing_set) if (tag->priv->letter_spacing_set)
dest->letter_spacing = vals->letter_spacing; dest->letter_spacing = vals->letter_spacing;
if (tag->priv->font_features_set)
dest->font_features = g_strdup (vals->font_features);
++n; ++n;
} }
@ -430,6 +442,7 @@ _gtk_text_tag_affects_size (GtkTextTag *tag)
priv->underline_set || priv->underline_set ||
priv->wrap_mode_set || priv->wrap_mode_set ||
priv->invisible_set || priv->invisible_set ||
priv->font_features_set ||
priv->letter_spacing_set; priv->letter_spacing_set;
} }

View File

@ -207,8 +207,23 @@ struct _GtkTextAttributes
/*< public >*/ /*< public >*/
gint letter_spacing; 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 >*/ /*< private >*/
guint padding[2]; guint padding[1];
#endif
#endif
}; };
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL

View File

@ -4837,6 +4837,10 @@ get_tag_for_attributes (PangoAttrIterator *iter)
if (attr) if (attr)
g_object_set (tag, "letter-spacing", ((PangoAttrInt*)attr)->value, NULL); 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; return tag;
} }

View File

@ -1639,10 +1639,9 @@ add_text_attrs (GtkTextLayout *layout,
if (style->font_scale != 1.0) if (style->font_scale != 1.0)
{ {
attr = pango_attr_scale_new (style->font_scale); attr = pango_attr_scale_new (style->font_scale);
attr->start_index = start; attr->start_index = start;
attr->end_index = start + byte_count; attr->end_index = start + byte_count;
pango_attr_list_insert (attrs, attr); pango_attr_list_insert (attrs, attr);
} }
@ -1661,6 +1660,15 @@ add_text_attrs (GtkTextLayout *layout,
attr->start_index = start; attr->start_index = start;
attr->end_index = start + byte_count; 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); pango_attr_list_insert (attrs, attr);
} }
} }

View File

@ -134,10 +134,11 @@ enum {
PROP_PARAGRAPH_BACKGROUND_RGBA, PROP_PARAGRAPH_BACKGROUND_RGBA,
PROP_FALLBACK, PROP_FALLBACK,
PROP_LETTER_SPACING, PROP_LETTER_SPACING,
PROP_FONT_FEATURES,
/* Behavior args */ /* Behavior args */
PROP_ACCUMULATIVE_MARGIN, PROP_ACCUMULATIVE_MARGIN,
/* Whether-a-style-arg-is-set args */ /* Whether-a-style-arg-is-set args */
PROP_BACKGROUND_SET, PROP_BACKGROUND_SET,
PROP_FOREGROUND_SET, PROP_FOREGROUND_SET,
@ -169,6 +170,7 @@ enum {
PROP_PARAGRAPH_BACKGROUND_SET, PROP_PARAGRAPH_BACKGROUND_SET,
PROP_FALLBACK_SET, PROP_FALLBACK_SET,
PROP_LETTER_SPACING_SET, PROP_LETTER_SPACING_SET,
PROP_FONT_FEATURES_SET,
LAST_ARG LAST_ARG
}; };
@ -676,6 +678,22 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
P_("Extra spacing between graphemes"), P_("Extra spacing between graphemes"),
0, G_MAXINT, 0, 0, G_MAXINT, 0,
GTK_PARAM_READWRITE)); 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: * GtkTextTag:accumulative-margin:
* *
@ -833,6 +851,10 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
P_("Letter spacing set"), P_("Letter spacing set"),
P_("Whether this tag affects letter spacing")); 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: * GtkTextTag::event:
* @tag: the #GtkTextTag on which the signal is emitted * @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"); g_object_notify (object, "letter-spacing-set");
break; 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: case PROP_ACCUMULATIVE_MARGIN:
priv->accumulative_margin = g_value_get_boolean (value); priv->accumulative_margin = g_value_get_boolean (value);
g_object_notify (object, "accumulative-margin"); 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); priv->letter_spacing_set = g_value_get_boolean (value);
break; break;
case PROP_FONT_FEATURES_SET:
priv->font_features_set = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -2002,6 +2034,10 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_int (value, priv->values->letter_spacing); g_value_set_int (value, priv->values->letter_spacing);
break; break;
case PROP_FONT_FEATURES:
g_value_set_string (value, priv->values->font_features);
break;
case PROP_ACCUMULATIVE_MARGIN: case PROP_ACCUMULATIVE_MARGIN:
g_value_set_boolean (value, priv->accumulative_margin); g_value_set_boolean (value, priv->accumulative_margin);
break; break;
@ -2118,6 +2154,10 @@ gtk_text_tag_get_property (GObject *object,
g_value_set_boolean (value, priv->letter_spacing_set); g_value_set_boolean (value, priv->letter_spacing_set);
break; break;
case PROP_FONT_FEATURES_SET:
g_value_set_boolean (value, priv->font_features_set);
break;
case PROP_BACKGROUND: case PROP_BACKGROUND:
case PROP_FOREGROUND: case PROP_FOREGROUND:
case PROP_PARAGRAPH_BACKGROUND: case PROP_PARAGRAPH_BACKGROUND:

View File

@ -77,6 +77,7 @@ struct _GtkTextTagPrivate
guint pg_bg_color_set : 1; guint pg_bg_color_set : 1;
guint fallback_set : 1; guint fallback_set : 1;
guint letter_spacing_set : 1; guint letter_spacing_set : 1;
guint font_features_set : 1;
/* Whether these margins accumulate or override */ /* Whether these margins accumulate or override */
guint accumulative_margin : 1; guint accumulative_margin : 1;