[gtk+/wip/pbor/css-text-attributes: 2/7] label: add support for CSS letter-spacing property



commit f31a462aca99caa3cfa26960977ef41a2b9267a7
Author: Paolo Borelli <pborelli gnome org>
Date:   Sat Jul 4 19:56:40 2015 +0200

    label: add support for CSS letter-spacing property
    
    Support letter-spacing CSS property on GtkLabel.
    Reftest is included.

 gtk/gtkcssstylepropertyimpl.c            |   19 +++++++++++++++++++
 gtk/gtkcsstypesprivate.h                 |   11 +++++++----
 gtk/gtklabel.c                           |   25 ++++++++++++++++++++++++-
 gtk/gtkstylecontext.c                    |   20 ++++++++++++++++++++
 gtk/gtkstylecontextprivate.h             |    2 ++
 testsuite/reftests/Makefile.am           |    4 ++++
 testsuite/reftests/letter-spacing.c      |   30 ++++++++++++++++++++++++++++++
 testsuite/reftests/letter-spacing.css    |    3 +++
 testsuite/reftests/letter-spacing.ref.ui |   17 +++++++++++++++++
 testsuite/reftests/letter-spacing.ui     |   16 ++++++++++++++++
 10 files changed, 142 insertions(+), 5 deletions(-)
---
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 45fa695..511165f 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -611,6 +611,15 @@ bindings_value_assign (GtkCssStyleProperty *property,
 }
 
 static GtkCssValue *
+parse_letter_spacing (GtkCssStyleProperty *property,
+                      GtkCssParser        *parser)
+{
+  return _gtk_css_number_value_parse (parser,
+                                      GTK_CSS_PARSE_LENGTH
+                                      | GTK_CSS_NUMBER_AS_PIXELS);
+}
+
+static GtkCssValue *
 box_shadow_value_parse (GtkCssStyleProperty *property,
                         GtkCssParser        *parser)
 {
@@ -1065,6 +1074,16 @@ _gtk_css_style_property_init_properties (void)
                                           assign_pango_stretch,
                                           _gtk_css_font_stretch_value_new (PANGO_STRETCH_NORMAL));
 
+  gtk_css_style_property_register        ("letter-spacing",
+                                          GTK_CSS_PROPERTY_LETTER_SPACING,
+                                          G_TYPE_NONE,
+                                          GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
+                                          GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS,
+                                          parse_letter_spacing,
+                                          NULL,
+                                          NULL,
+                                          _gtk_css_number_value_new (0.0, GTK_CSS_PX));
+
   gtk_css_style_property_register        ("text-shadow",
                                           GTK_CSS_PROPERTY_TEXT_SHADOW,
                                           G_TYPE_NONE,
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index 1f68e9c..76cae97 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -78,6 +78,7 @@ typedef enum { /*< skip >*/
  * @GTK_CSS_AFFECTS_FONT: The font is affected and should be reloaded
  *   if it was cached.
  * @GTK_CSS_AFFECTS_TEXT: Text rendering is affected.
+ * @GTK_CSS_AFFECTS_TEXT_ATTRS: Text attributes are affected.
  * @GTK_CSS_AFFECTS_ICON: Icons and icon rendering is affected.
  * @GTK_CSS_AFFECTS_OUTLINE: The outline styling is affected. Outlines
  *   only affect elements that can be focused.
@@ -99,10 +100,11 @@ typedef enum {
   GTK_CSS_AFFECTS_BORDER = (1 << 2),
   GTK_CSS_AFFECTS_FONT = (1 << 3),
   GTK_CSS_AFFECTS_TEXT = (1 << 4),
-  GTK_CSS_AFFECTS_ICON = (1 << 5),
-  GTK_CSS_AFFECTS_OUTLINE = (1 << 6),
-  GTK_CSS_AFFECTS_CLIP = (1 << 7),
-  GTK_CSS_AFFECTS_SIZE = (1 << 8)
+  GTK_CSS_AFFECTS_TEXT_ATTRS = (1 << 5),
+  GTK_CSS_AFFECTS_ICON = (1 << 6),
+  GTK_CSS_AFFECTS_OUTLINE = (1 << 7),
+  GTK_CSS_AFFECTS_CLIP = (1 << 8),
+  GTK_CSS_AFFECTS_SIZE = (1 << 9)
 } GtkCssAffects;
 
 enum { /*< skip >*/
@@ -116,6 +118,7 @@ enum { /*< skip >*/
   GTK_CSS_PROPERTY_FONT_VARIANT,
   GTK_CSS_PROPERTY_FONT_WEIGHT,
   GTK_CSS_PROPERTY_FONT_STRETCH,
+  GTK_CSS_PROPERTY_LETTER_SPACING,
   GTK_CSS_PROPERTY_TEXT_SHADOW,
   GTK_CSS_PROPERTY_BOX_SHADOW,
   GTK_CSS_PROPERTY_MARGIN_TOP,
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 88fc284..92b8ee9 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -35,6 +35,7 @@
 #include "gtkbuilderprivate.h"
 #include "gtkclipboard.h"
 #include "gtkcssshadowsvalueprivate.h"
+#include "gtkcssstylepropertyprivate.h"
 #include "gtkdnd.h"
 #include "gtkimage.h"
 #include "gtkintl.h"
@@ -3412,6 +3413,7 @@ gtk_label_update_layout_attributes (GtkLabel *label)
   GtkWidget *widget = GTK_WIDGET (label);
   GtkStyleContext *context;
   PangoAttrList *attrs;
+  PangoAttrList *style_attrs;
 
   if (priv->layout == NULL)
     return;
@@ -3462,6 +3464,17 @@ gtk_label_update_layout_attributes (GtkLabel *label)
   else
     attrs = NULL;
 
+  style_attrs = _gtk_style_context_get_pango_attributes (context);
+  if (style_attrs)
+    {
+      if (attrs)
+        _gtk_pango_attr_list_merge (attrs, style_attrs);
+      else
+        attrs = pango_attr_list_ref (style_attrs);
+
+      pango_attr_list_unref (style_attrs);
+    }
+
   if (priv->markup_attrs)
     {
       if (attrs)
@@ -4124,12 +4137,22 @@ gtk_label_state_flags_changed (GtkWidget     *widget,
 static void 
 gtk_label_style_updated (GtkWidget *widget)
 {
+  static GtkBitmask *affects_text_attrs = NULL;
   GtkLabel *label = GTK_LABEL (widget);
   GtkLabelPrivate *priv = label->priv;
+  GtkStyleContext *context;
+  const GtkBitmask *changes;;
+
+  if (G_UNLIKELY (affects_text_attrs == NULL))
+    affects_text_attrs = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_TEXT_ATTRS);
 
   GTK_WIDGET_CLASS (gtk_label_parent_class)->style_updated (widget);
 
-  if (priv->select_info && priv->select_info->links)
+  context = gtk_widget_get_style_context (widget);
+  changes = _gtk_style_context_get_changes (context);
+
+  if (changes == NULL || _gtk_bitmask_intersects (changes, affects_text_attrs) ||
+      (priv->select_info && priv->select_info->links))
     gtk_label_update_layout_attributes (label);
 }
 
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index df31eb0..c34edd1 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -3148,6 +3148,26 @@ _gtk_style_context_get_icon_extents (GtkStyleContext *context,
   extents->height += border.top + border.bottom;
 }
 
+PangoAttrList *
+_gtk_style_context_get_pango_attributes (GtkStyleContext *context)
+{
+  gint letter_spacing;
+  PangoAttrList *attrs = NULL;
+
+  letter_spacing = _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_LETTER_SPACING), 100);
+  if (letter_spacing != 0)
+    {
+      PangoAttribute *letter_spacing_attr;
+
+      letter_spacing_attr = pango_attr_letter_spacing_new (letter_spacing * PANGO_SCALE);
+
+      attrs = pango_attr_list_new ();
+      pango_attr_list_insert (attrs, letter_spacing_attr);
+    }
+
+    return attrs;
+}
+
 static AtkAttributeSet *
 add_attribute (AtkAttributeSet  *attributes,
                AtkTextAttribute  attr,
diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h
index 40fd4f1..1ed7b21 100644
--- a/gtk/gtkstylecontextprivate.h
+++ b/gtk/gtkstylecontextprivate.h
@@ -64,6 +64,8 @@ void           _gtk_style_context_get_icon_extents           (GtkStyleContext
                                                               gint                width,
                                                               gint                height);
 
+PangoAttrList *_gtk_style_context_get_pango_attributes       (GtkStyleContext *context);
+
 /* Accessibility support */
 AtkAttributeSet *_gtk_style_context_get_attributes           (AtkAttributeSet    *attributes,
                                                               GtkStyleContext    *context,
diff --git a/testsuite/reftests/Makefile.am b/testsuite/reftests/Makefile.am
index 3887acc..67a918f 100644
--- a/testsuite/reftests/Makefile.am
+++ b/testsuite/reftests/Makefile.am
@@ -323,6 +323,9 @@ testdata = \
        label-width-chars-dont-shrink.ui \
        label-wrap-justify.ref.ui \
        label-wrap-justify.ui \
+       letter-spacing.css \
+       letter-spacing.ui \
+       letter-spacing.ref.ui \
        linear-gradient.css \
        linear-gradient.ref.ui \
        linear-gradient.ui \
@@ -498,6 +501,7 @@ libreftest_la_LIBADD = $(gtk_reftest_LDADD)
 libreftest_la_SOURCES =                        \
        expand-expander.c               \
        label-text-shadow-changes-modify-clip.c \
+       letter-spacing.c                \
        set-default-direction.c         \
        statusbar-remove-all.c          \
        textview-border-windows.c       \
diff --git a/testsuite/reftests/letter-spacing.c b/testsuite/reftests/letter-spacing.c
new file mode 100644
index 0000000..5e876f0
--- /dev/null
+++ b/testsuite/reftests/letter-spacing.c
@@ -0,0 +1,30 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+
+G_MODULE_EXPORT void
+set_letter_spacing (GtkLabel *label)
+{
+  PangoAttrList *attrs;
+
+  attrs = pango_attr_list_new ();
+  pango_attr_list_insert (attrs, pango_attr_letter_spacing_new (10 * PANGO_SCALE));
+  gtk_label_set_attributes (label, attrs);
+  pango_attr_list_unref (attrs);
+}
diff --git a/testsuite/reftests/letter-spacing.css b/testsuite/reftests/letter-spacing.css
new file mode 100644
index 0000000..9bf4eef
--- /dev/null
+++ b/testsuite/reftests/letter-spacing.css
@@ -0,0 +1,3 @@
+#spaced {
+  letter-spacing: 10px;
+}
diff --git a/testsuite/reftests/letter-spacing.ref.ui b/testsuite/reftests/letter-spacing.ref.ui
new file mode 100644
index 0000000..f1925ba
--- /dev/null
+++ b/testsuite/reftests/letter-spacing.ref.ui
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.1 -->
+<interface>
+  <requires lib="gtk+" version="3.0"/>
+  <object class="GtkWindow" id="window1">
+    <property name="can_focus">False</property>
+    <property name="type">popup</property>
+    <child>
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label">abc</property>
+        <signal name="map" handler="reftest:set_letter_spacing" swapped="no"/>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/testsuite/reftests/letter-spacing.ui b/testsuite/reftests/letter-spacing.ui
new file mode 100644
index 0000000..f93785f
--- /dev/null
+++ b/testsuite/reftests/letter-spacing.ui
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkWindow" id="window1">
+    <property name="can_focus">False</property>
+    <property name="type">popup</property>
+    <child>
+      <object class="GtkLabel" id="label1">
+        <property name="name">spaced</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label">abc</property>
+      </object>
+    </child>
+  </object>
+</interface>


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