summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-08-04 09:43:08 -0400
committerMatthias Clasen <mclasen@redhat.com>2019-08-04 10:37:44 -0400
commit2e6f2eb8148220b09d4834065d53c73a3ac2427b (patch)
tree9fce36e84330531009328f2054262a4f3eddd68f
parent1284511871dd80592ef862fcc5ccb5639ac9fe0e (diff)
downloadpango-2e6f2eb8148220b09d4834065d53c73a3ac2427b.tar.gz
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.
-rw-r--r--docs/pango-sections.txt1
-rw-r--r--pango/pango-attributes.c27
-rw-r--r--pango/pango-attributes.h4
-rw-r--r--pango/pango-layout.c37
-rw-r--r--pango/pango-markup.c18
-rw-r--r--tests/test-common.c1
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
@@ -1207,6 +1207,33 @@ pango_attr_allow_breaks_new (gboolean 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;