[gtk/css-line-decoration] textview: Apply font features from css



commit 8ac2e8d49554c28224cf6ed8f2807e8ffdac2164
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Aug 26 20:21:23 2021 -0400

    textview: Apply font features from css
    
    We were forgetting to propagate these values from
    CSS to the default attributes. Share the code for
    getting these values out of a GtkCssStyle.

 gtk/gtkcssstyle.c        | 161 +++++++++++++++++++++++++----------------------
 gtk/gtkcssstyleprivate.h |   7 ++-
 gtk/gtktextview.c        |  35 ++++++-----
 3 files changed, 110 insertions(+), 93 deletions(-)
---
diff --git a/gtk/gtkcssstyle.c b/gtk/gtkcssstyle.c
index 652f9a7a78..31b5d3e2c9 100644
--- a/gtk/gtkcssstyle.c
+++ b/gtk/gtkcssstyle.c
@@ -402,10 +402,10 @@ get_pango_underline_from_style (GtkTextDecorationStyle style)
   g_return_val_if_reached (PANGO_UNDERLINE_SINGLE);
 }
 
-static PangoTextTransform
-get_pango_text_transform_from_style (GtkTextTransform transform)
+PangoTextTransform
+gtk_css_style_get_pango_text_transform (GtkCssStyle *style)
 {
-  switch (transform)
+  switch (_gtk_css_text_transform_value_get (style->font_variant->text_transform))
     {
     case GTK_CSS_TEXT_TRANSFORM_NONE:
       return PANGO_TEXT_TRANSFORM_NONE;
@@ -451,77 +451,14 @@ append_separated (GString    **s,
   g_string_append (*s, text);
 }
 
-PangoAttrList *
-gtk_css_style_get_pango_attributes (GtkCssStyle *style)
+char *
+gtk_css_style_compute_font_features (GtkCssStyle *style)
 {
-  PangoAttrList *attrs = NULL;
-  GtkTextDecorationLine decoration_line;
-  GtkTextDecorationStyle decoration_style;
-  const GdkRGBA *color;
-  const GdkRGBA *decoration_color;
-  int letter_spacing;
   GtkCssFontVariantLigature ligatures;
   GtkCssFontVariantNumeric numeric;
   GtkCssFontVariantEastAsian east_asian;
-  GString *s;
   char *settings;
-  GtkTextTransform transform;
-
-  /* text-decoration */
-  decoration_line = _gtk_css_text_decoration_line_value_get (style->font_variant->text_decoration_line);
-  decoration_style = _gtk_css_text_decoration_style_value_get (style->font_variant->text_decoration_style);
-  color = gtk_css_color_value_get_rgba (style->core->color);
-  decoration_color = gtk_css_color_value_get_rgba (style->font_variant->text_decoration_color
-                                                   ? style->font_variant->text_decoration_color
-                                                   : style->core->color);
-
-  if (decoration_line & GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE)
-    {
-      attrs = add_pango_attr (attrs, pango_attr_underline_new (get_pango_underline_from_style 
(decoration_style)));
-      if (!gdk_rgba_equal (color, decoration_color))
-        attrs = add_pango_attr (attrs, pango_attr_underline_color_new (decoration_color->red * 65535. + 0.5,
-                                                                       decoration_color->green * 65535. + 
0.5,
-                                                                       decoration_color->blue * 65535. + 
0.5));
-    }
-  if (decoration_line & GTK_CSS_TEXT_DECORATION_LINE_OVERLINE)
-    {
-      attrs = add_pango_attr (attrs, pango_attr_overline_new (get_pango_overline_from_style 
(decoration_style)));
-      if (!gdk_rgba_equal (color, decoration_color))
-        attrs = add_pango_attr (attrs, pango_attr_overline_color_new (decoration_color->red * 65535. + 0.5,
-                                                                      decoration_color->green * 65535. + 0.5,
-                                                                      decoration_color->blue * 65535. + 
0.5));
-    }
-  if (decoration_line & GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH)
-    {
-      attrs = add_pango_attr (attrs, pango_attr_strikethrough_new (TRUE));
-      if (!gdk_rgba_equal (color, decoration_color))
-        attrs = add_pango_attr (attrs, pango_attr_strikethrough_color_new (decoration_color->red * 65535. + 
0.5,
-                                                                           decoration_color->green * 65535. 
+ 0.5,
-                                                                           decoration_color->blue * 65535. + 
0.5));
-    }
-
-  /* letter-spacing */
-  letter_spacing = _gtk_css_number_value_get (style->font->letter_spacing, 100);
-  if (letter_spacing != 0)
-    {
-      attrs = add_pango_attr (attrs, pango_attr_letter_spacing_new (letter_spacing * PANGO_SCALE));
-    }
-
-  /* line-height */
-  {
-    double height = gtk_css_line_height_value_get (style->font->line_height);
-    if (height != 0.0)
-      {
-        if (gtk_css_number_value_get_dimension (style->font->line_height) == GTK_CSS_DIMENSION_LENGTH)
-          attrs = add_pango_attr (attrs, pango_attr_line_height_new_absolute (height * PANGO_SCALE));
-        else
-          attrs = add_pango_attr (attrs, pango_attr_line_height_new (height));
-      }
-   }
-
-  /* OpenType features */
-
-  s = NULL;
+  GString *s = NULL;
 
   switch (_gtk_css_font_kerning_value_get (style->font_variant->font_kerning))
     {
@@ -671,15 +608,91 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style)
     }
 
   if (s)
+    return g_string_free (s, FALSE);
+  else
+    return NULL;
+}
+
+PangoAttrList *
+gtk_css_style_get_pango_attributes (GtkCssStyle *style)
+{
+  PangoAttrList *attrs = NULL;
+  GtkTextDecorationLine decoration_line;
+  GtkTextDecorationStyle decoration_style;
+  const GdkRGBA *color;
+  const GdkRGBA *decoration_color;
+  int letter_spacing;
+
+  /* text-decoration */
+  decoration_line = _gtk_css_text_decoration_line_value_get (style->font_variant->text_decoration_line);
+  decoration_style = _gtk_css_text_decoration_style_value_get (style->font_variant->text_decoration_style);
+  color = gtk_css_color_value_get_rgba (style->core->color);
+  decoration_color = gtk_css_color_value_get_rgba (style->font_variant->text_decoration_color
+                                                   ? style->font_variant->text_decoration_color
+                                                   : style->core->color);
+
+  if (decoration_line & GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE)
     {
-      attrs = add_pango_attr (attrs, pango_attr_font_features_new (s->str));
-      g_string_free (s, TRUE);
+      attrs = add_pango_attr (attrs, pango_attr_underline_new (get_pango_underline_from_style 
(decoration_style)));
+      if (!gdk_rgba_equal (color, decoration_color))
+        attrs = add_pango_attr (attrs, pango_attr_underline_color_new (decoration_color->red * 65535. + 0.5,
+                                                                       decoration_color->green * 65535. + 
0.5,
+                                                                       decoration_color->blue * 65535. + 
0.5));
+    }
+  if (decoration_line & GTK_CSS_TEXT_DECORATION_LINE_OVERLINE)
+    {
+      attrs = add_pango_attr (attrs, pango_attr_overline_new (get_pango_overline_from_style 
(decoration_style)));
+      if (!gdk_rgba_equal (color, decoration_color))
+        attrs = add_pango_attr (attrs, pango_attr_overline_color_new (decoration_color->red * 65535. + 0.5,
+                                                                      decoration_color->green * 65535. + 0.5,
+                                                                      decoration_color->blue * 65535. + 
0.5));
+    }
+  if (decoration_line & GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH)
+    {
+      attrs = add_pango_attr (attrs, pango_attr_strikethrough_new (TRUE));
+      if (!gdk_rgba_equal (color, decoration_color))
+        attrs = add_pango_attr (attrs, pango_attr_strikethrough_color_new (decoration_color->red * 65535. + 
0.5,
+                                                                           decoration_color->green * 65535. 
+ 0.5,
+                                                                           decoration_color->blue * 65535. + 
0.5));
     }
 
-  transform = _gtk_css_text_transform_value_get (style->font_variant->text_transform);
+  /* letter-spacing */
+  letter_spacing = _gtk_css_number_value_get (style->font->letter_spacing, 100);
+  if (letter_spacing != 0)
+    {
+      attrs = add_pango_attr (attrs, pango_attr_letter_spacing_new (letter_spacing * PANGO_SCALE));
+    }
+
+  /* line-height */
+  {
+    double height = gtk_css_line_height_value_get (style->font->line_height);
+    if (height != 0.0)
+      {
+        if (gtk_css_number_value_get_dimension (style->font->line_height) == GTK_CSS_DIMENSION_LENGTH)
+          attrs = add_pango_attr (attrs, pango_attr_line_height_new_absolute (height * PANGO_SCALE));
+        else
+          attrs = add_pango_attr (attrs, pango_attr_line_height_new (height));
+      }
+   }
+
+  /* OpenType features */
+  {
+    char *font_features = gtk_css_style_compute_font_features (style);
+
+    if (font_features)
+      {
+        attrs = add_pango_attr (attrs, pango_attr_font_features_new (font_features));
+        g_free (font_features);
+      }
+  }
+
+  /* text-transform */
+  {
+    PangoTextTransform transform = gtk_css_style_get_pango_text_transform (style);
 
-  if (transform != GTK_CSS_TEXT_TRANSFORM_NONE)
-    attrs = add_pango_attr (attrs, pango_attr_text_transform_new (get_pango_text_transform_from_style 
(transform)));
+    if (transform != PANGO_TEXT_TRANSFORM_NONE)
+      attrs = add_pango_attr (attrs, pango_attr_text_transform_new (transform));
+  }
 
   return attrs;
 }
diff --git a/gtk/gtkcssstyleprivate.h b/gtk/gtkcssstyleprivate.h
index da878606f0..d618b7d741 100644
--- a/gtk/gtkcssstyleprivate.h
+++ b/gtk/gtkcssstyleprivate.h
@@ -256,17 +256,18 @@ GtkCssValue *           gtk_css_style_get_value                 (GtkCssStyle
 GtkCssSection *         gtk_css_style_get_section               (GtkCssStyle            *style,
                                                                  guint                   id) G_GNUC_PURE;
 gboolean                gtk_css_style_is_static                 (GtkCssStyle            *style) G_GNUC_PURE;
+GtkCssStaticStyle *     gtk_css_style_get_static_style          (GtkCssStyle            *style);
 
 char *                  gtk_css_style_to_string                 (GtkCssStyle            *style);
 gboolean                gtk_css_style_print                     (GtkCssStyle            *style,
                                                                  GString                *string,
                                                                  guint                   indent,
                                                                  gboolean                skip_initial);
-PangoAttrList *         gtk_css_style_get_pango_attributes      (GtkCssStyle            *style);
 
+PangoTextTransform      gtk_css_style_get_pango_text_transform  (GtkCssStyle            *style);
+char *                  gtk_css_style_compute_font_features     (GtkCssStyle            *style);
+PangoAttrList *         gtk_css_style_get_pango_attributes      (GtkCssStyle            *style);
 PangoFontDescription *  gtk_css_style_get_pango_font            (GtkCssStyle            *style);
-GtkCssStaticStyle *     gtk_css_style_get_static_style          (GtkCssStyle            *style);
-
 
 GtkCssValues *gtk_css_values_new   (GtkCssValuesType  type);
 GtkCssValues *gtk_css_values_ref   (GtkCssValues     *values);
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 087cbd4f12..38126a27b8 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -7708,20 +7708,8 @@ gtk_text_view_set_attributes_from_style (GtkTextView        *text_view,
 
   values->font = gtk_css_style_get_pango_font (style);
 
-  values->line_height = 0.0;
-  values->line_height_is_absolute = FALSE;
-
-  height = gtk_css_line_height_value_get (style->font->line_height);
-  if (height != 0.0)
-    {
-      values->line_height = height;
-      if (gtk_css_number_value_get_dimension (style->font->line_height) == GTK_CSS_DIMENSION_LENGTH)
-        values->line_height_is_absolute = TRUE;
-    }
-
-  values->letter_spacing = _gtk_css_number_value_get (style->font->letter_spacing, 100) * PANGO_SCALE;
-
   /* text-decoration */
+
   decoration_line = _gtk_css_text_decoration_line_value_get (style->font_variant->text_decoration_line);
   decoration_style = _gtk_css_text_decoration_style_value_get (style->font_variant->text_decoration_style);
   color = gtk_css_color_value_get_rgba (style->core->color);
@@ -7774,10 +7762,25 @@ gtk_text_view_set_attributes_from_style (GtkTextView        *text_view,
       values->appearance.strikethrough_rgba = NULL;
     }
 
-  /* text-transform */
+  /* letter-spacing */
+  values->letter_spacing = _gtk_css_number_value_get (style->font->letter_spacing, 100) * PANGO_SCALE;
+
+  /* line-height */
+
+  values->line_height = gtk_css_line_height_value_get (style->font->line_height);
+  values->line_height_is_absolute = FALSE;
+  if (values->line_height != 0.0)
+    {
+      if (gtk_css_number_value_get_dimension (style->font->line_height) == GTK_CSS_DIMENSION_LENGTH)
+        values->line_height_is_absolute = TRUE;
+    }
 
-  transform = _gtk_css_text_transform_value_get (style->font_variant->text_transform);
-  values->text_transform = get_pango_text_transform_from_style (transform);
+  /* OpenType features */
+  g_free (values->font_features);
+  values->font_features = gtk_css_style_compute_font_features (style);
+
+  /* text-transform */
+  values->text_transform = gtk_css_style_get_pango_text_transform (style);
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]