[pango/hyphen-control: 1/2] Add an insert-hyphens attribute



commit 2e6f2eb8148220b09d4834065d53c73a3ac2427b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Aug 4 09:43:08 2019 -0400

    Add an insert-hyphens attribute
    
    Add a text attribute that allows to suppress
    insertion of hyphens at intra-word line breaks.
    
    This is useful for non-paragraph-like contexts,
    where line breaks are needed, but hyphens are not
    expected.

 docs/pango-sections.txt  |  1 +
 pango/pango-attributes.c | 27 +++++++++++++++++++++++++++
 pango/pango-attributes.h |  4 ++++
 pango/pango-layout.c     | 37 +++++++++++++++++++++++++++++++++++--
 pango/pango-markup.c     | 18 ++++++++++++++++++
 tests/test-common.c      |  1 +
 6 files changed, 86 insertions(+), 2 deletions(-)
---
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index 7a95d401..c179633b 100644
--- a/docs/pango-sections.txt
+++ b/docs/pango-sections.txt
@@ -413,6 +413,7 @@ pango_attr_font_features_new
 pango_attr_foreground_alpha_new
 pango_attr_background_alpha_new
 pango_attr_allow_breaks_new
+pango_attr_insert_hyphens_new
 PangoShowFlags
 pango_attr_show_new
 PangoColor
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 2f02e264..9a80f0e1 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -1206,6 +1206,33 @@ pango_attr_allow_breaks_new (gboolean allow_breaks)
   return pango_attr_int_new (&klass, (int)allow_breaks);
 }
 
+/**
+ * pango_attr_insert_hyphens_new:
+ * @insert_hyphens: %TRUE if hyphens should be inserted
+ *
+ * Create a new insert-hyphens attribute.
+ *
+ * Pango will insert hyphens when breaking lines in the middle
+ * of a word. This attribute can be used to suppress the hyphen.
+ *
+ * Return value: (transfer full): the newly allocated #PangoAttribute,
+ *               which should be freed with pango_attribute_destroy()
+ *
+ * Since: 1.44
+ */
+PangoAttribute *
+pango_attr_insert_hyphens_new (gboolean insert_hyphens)
+{
+  static const PangoAttrClass klass = {
+    PANGO_ATTR_INSERT_HYPHENS,
+    pango_attr_int_copy,
+    pango_attr_int_destroy,
+    pango_attr_int_equal,
+  };
+
+  return pango_attr_int_new (&klass, (int)insert_hyphens);
+}
+
 /**
  * pango_attr_show_new:
  * @flags: #PangoShowFlags to apply
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index b9ab6459..f60806f4 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -149,6 +149,7 @@ typedef struct _PangoAttrIterator PangoAttrIterator;
  * @PANGO_ATTR_BACKGROUND_ALPHA: background alpha (#PangoAttrInt). Since 1.38
  * @PANGO_ATTR_ALLOW_BREAKS: whether breaks are allowed (#PangoAttrInt). Since 1.44
  * @PANGO_ATTR_SHOW: how to render invisible characters (#PangoAttrInt). Since 1.44
+ * @PANGO_ATTR_INSERT_HYPHENS: whether to insert hyphens at intra-word line breaks (#PangoAttrInt). Since 
1.44
  *
  * The #PangoAttrType
  * distinguishes between different types of attributes. Along with the
@@ -187,6 +188,7 @@ typedef enum
   PANGO_ATTR_BACKGROUND_ALPHA, /* PangoAttrInt */
   PANGO_ATTR_ALLOW_BREAKS,     /* PangoAttrInt */
   PANGO_ATTR_SHOW,             /* PangoAttrInt */
+  PANGO_ATTR_INSERT_HYPHENS,   /* PangoAttrInt */
 } PangoAttrType;
 
 /**
@@ -528,6 +530,8 @@ PANGO_AVAILABLE_IN_1_38
 PangoAttribute *pango_attr_background_alpha_new (guint16 alpha);
 PANGO_AVAILABLE_IN_1_44
 PangoAttribute *pango_attr_allow_breaks_new     (gboolean allow_breaks);
+PANGO_AVAILABLE_IN_1_44
+PangoAttribute *pango_attr_insert_hyphens_new   (gboolean insert_hyphens);
 
 /**
  * PangoShowFlags:
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 0ddb6e14..725ef0e0 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3327,7 +3327,7 @@ struct _ParaBreakState
   int log_widths_offset;        /* Offset into log_widths to the point corresponding
                                 * to the remaining portion of the first item */
 
-  int *need_hyphen;             /* is this char a soft hyphen ? */
+  int *need_hyphen;             /* Insert a hyphen if breaking here ? */
   int line_start_index;                /* Start index (byte offset) of line in layout->text */
   int line_start_offset;       /* Character offset of line in layout->text */
 
@@ -3432,12 +3432,41 @@ get_need_hyphen (PangoItem  *item,
   const char *p;
   gboolean prev_space;
   gboolean prev_hyphen;
+  PangoAttrList *attrs;
+  PangoAttrIterator *iter;
+  GSList *l;
+
+  attrs = pango_attr_list_new ();
+  for (l = item->analysis.extra_attrs; l; l = l->next)
+    {
+      PangoAttribute *attr = l->data;
+      if (attr->klass->type == PANGO_ATTR_INSERT_HYPHENS)
+        pango_attr_list_change (attrs, pango_attribute_copy (attr));
+    }
+  iter = pango_attr_list_get_iterator (attrs);
 
   for (i = 0, p = text + item->offset; i < item->num_chars; i++, p = g_utf8_next_char (p))
     {
       gunichar wc = g_utf8_get_char (p);
       gboolean space;
       gboolean hyphen;
+      int start, end, pos;
+      gboolean insert_hyphens = TRUE;
+
+      pos = p - text;
+      do {
+        pango_attr_iterator_range (iter, &start, &end);
+        if (end > pos)
+          break;
+      } while (pango_attr_iterator_next (iter));
+
+      if (start <= pos && pos < end)
+        {
+          PangoAttribute *attr;
+          attr = pango_attr_iterator_get (iter, PANGO_ATTR_INSERT_HYPHENS);
+          if (attr)
+            insert_hyphens = ((PangoAttrInt*)attr)->value;
+        }
 
       switch (g_unichar_type (wc))
         {
@@ -3479,11 +3508,14 @@ get_need_hyphen (PangoItem  *item,
       else if (prev_hyphen || hyphen)
         need_hyphen[i] = FALSE;
       else
-        need_hyphen[i] = TRUE;
+        need_hyphen[i] = insert_hyphens;
 
       prev_space = space;
       prev_hyphen = hyphen;
     }
+
+  pango_attr_iterator_destroy (iter);
+  pango_attr_list_unref (attrs);
 }
 
 static gboolean
@@ -4074,6 +4106,7 @@ affects_break_or_shape (PangoAttribute *attr,
     /* Affects breaks */
     case PANGO_ATTR_ALLOW_BREAKS:
     /* Affects shaping */
+    case PANGO_ATTR_INSERT_HYPHENS:
     case PANGO_ATTR_FONT_FEATURES:
     case PANGO_ATTR_SHOW:
       return TRUE;
diff --git a/pango/pango-markup.c b/pango/pango-markup.c
index e39730e4..6dce1b2e 100644
--- a/pango/pango-markup.c
+++ b/pango/pango-markup.c
@@ -158,6 +158,10 @@
  *   not allowed, the range will be kept in a single run as far
  *   as possible. Breaks are allowed by default.
  *
+ * insert_hyphens
+ * : 'true' or 'false' whether to insert hyphens when breaking
+ *   lines in the middle of a word. Hyphens are inserted by default.
+ *
  * show
  * : A value determining how invisible characters are treated.
  *   Possible values are 'spaces', 'line-breaks', 'ignorables'
@@ -1334,6 +1338,7 @@ span_parse_func     (MarkupData            *md G_GNUC_UNUSED,
   const char *alpha = NULL;
   const char *background_alpha = NULL;
   const char *allow_breaks = NULL;
+  const char *insert_hyphens = NULL;
   const char *show = NULL;
 
   g_markup_parse_context_get_position (context,
@@ -1407,6 +1412,9 @@ span_parse_func     (MarkupData            *md G_GNUC_UNUSED,
        CHECK_ATTRIBUTE (gravity);
        CHECK_ATTRIBUTE (gravity_hint);
        break;
+      case 'i':
+        CHECK_ATTRIBUTE (insert_hyphens);
+        break;
       case 'l':
        CHECK_ATTRIBUTE (lang);
        CHECK_ATTRIBUTE (letter_spacing);
@@ -1767,6 +1775,16 @@ span_parse_func     (MarkupData            *md G_GNUC_UNUSED,
       add_attribute (tag, pango_attr_allow_breaks_new (b));
     }
 
+  if (G_UNLIKELY (insert_hyphens))
+    {
+      gboolean b = FALSE;
+
+      if (!span_parse_boolean ("insert_hyphens", insert_hyphens, &b, line_number, error))
+       goto error;
+
+      add_attribute (tag, pango_attr_insert_hyphens_new (b));
+    }
+
   return TRUE;
 
  error:
diff --git a/tests/test-common.c b/tests/test-common.c
index 3b1620ed..012059f4 100644
--- a/tests/test-common.c
+++ b/tests/test-common.c
@@ -119,6 +119,7 @@ print_attribute (PangoAttribute *attr, GString *string)
     case PANGO_ATTR_FOREGROUND_ALPHA:
     case PANGO_ATTR_BACKGROUND_ALPHA:
     case PANGO_ATTR_ALLOW_BREAKS:
+    case PANGO_ATTR_INSERT_HYPHENS:
     case PANGO_ATTR_SHOW:
       g_string_append_printf (string, "%d", ((PangoAttrInt *)attr)->value);
       break;


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