summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-15 20:58:13 -0400
committerMatthias Clasen <mclasen@redhat.com>2019-07-16 21:11:11 -0400
commit0cd54d89c78ab8a0a77afb41d65421fcac45dd85 (patch)
tree7e08326b8046ca378a6894558709cdfec67b5bf7
parentc3e05ce8759d9858ec14c4ade2f5987b90b42c6b (diff)
downloadpango-0cd54d89c78ab8a0a77afb41d65421fcac45dd85.tar.gz
Don't insert extra runs for hyphens
Instead, reshape the pre-break run with the soft hyphen replaced by an actual hyphen. This is unfortunately inefficient, we copy the entire text for this. The alternative (scatter-gather populating the harfbuzz buffer) is too hard to manage.
-rw-r--r--pango/pango-layout.c79
1 files changed, 41 insertions, 38 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 21897e29..00c78584 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3310,7 +3310,8 @@ should_ellipsize_current_line (PangoLayout *layout,
static PangoGlyphString *
shape_run (PangoLayoutLine *line,
ParaBreakState *state,
- PangoItem *item)
+ PangoItem *item,
+ gboolean with_hyphen)
{
PangoLayout *layout = line->layout;
PangoGlyphString *glyphs = pango_glyph_string_new ();
@@ -3324,9 +3325,30 @@ shape_run (PangoLayoutLine *line,
state->properties.shape_ink_rect, state->properties.shape_logical_rect,
glyphs);
else
- pango_shape_full (layout->text + item->offset, item->length,
- layout->text, layout->length,
- &item->analysis, glyphs);
+ {
+
+ if (with_hyphen)
+ {
+ GString *s = g_string_new ("");
+
+ g_string_append_len (s, layout->text, item->offset + item->length - 2);
+ g_string_append (s, "-");
+ g_string_append_len (s, layout->text + item->offset + item->length, layout->length - (item->offset + item->length));
+
+ pango_shape_full (s->str + item->offset, item->length - 1,
+ s->str, s->len,
+ &item->analysis, glyphs);
+
+ g_string_free (s, TRUE);
+
+ }
+ else
+ {
+ pango_shape_full (layout->text + item->offset, item->length,
+ layout->text, layout->length,
+ &item->analysis, glyphs);
+ }
+ }
if (state->properties.letter_spacing)
{
@@ -3356,7 +3378,8 @@ static void
insert_run (PangoLayoutLine *line,
ParaBreakState *state,
PangoItem *run_item,
- gboolean last_run)
+ gboolean last_run,
+ gboolean with_hyphen)
{
PangoLayoutRun *run = g_slice_new (PangoLayoutRun);
@@ -3365,7 +3388,7 @@ insert_run (PangoLayoutLine *line,
if (last_run && state->log_widths_offset == 0)
run->glyphs = state->glyphs;
else
- run->glyphs = shape_run (line, state, run_item);
+ run->glyphs = shape_run (line, state, run_item, with_hyphen);
if (last_run)
{
@@ -3503,23 +3526,6 @@ find_break_extra_width (PangoLayout *layout,
return 0;
}
-static void
-insert_hyphen_after (PangoLayoutLine *line,
- ParaBreakState *state,
- PangoItem *item)
-{
- PangoLayout *layout = line->layout;
- PangoLayoutRun *run;
-
- /* Use the SHY as text for the hyphen run */
- item->num_chars -= 1;
- item->length -= 2;
- run = create_hyphen_run (layout, item);
- line->runs = g_slist_prepend (line->runs, run);
-
- state->remaining_width -= pango_glyph_string_get_width (run->glyphs);
-}
-
#if 0
# define DEBUG debug
void
@@ -3577,7 +3583,7 @@ process_item (PangoLayout *layout,
if (!state->glyphs)
{
pango_layout_get_item_properties (item, &state->properties);
- state->glyphs = shape_run (line, state, item);
+ state->glyphs = shape_run (line, state, item, FALSE);
state->log_widths = NULL;
state->need_hyphen = NULL;
@@ -3590,7 +3596,7 @@ process_item (PangoLayout *layout,
g_utf8_get_char (layout->text + item->offset) == LINE_SEPARATOR &&
!should_ellipsize_current_line (layout, state))
{
- insert_run (line, state, item, TRUE);
+ insert_run (line, state, item, TRUE, FALSE);
state->log_widths_offset += item->num_chars;
return BREAK_LINE_SEPARATOR;
@@ -3598,7 +3604,7 @@ process_item (PangoLayout *layout,
if (state->remaining_width < 0 && !no_break_at_end) /* Wrapping off */
{
- insert_run (line, state, item, TRUE);
+ insert_run (line, state, item, TRUE, FALSE);
return BREAK_ALL_FIT;
}
@@ -3619,7 +3625,7 @@ process_item (PangoLayout *layout,
{
state->remaining_width -= width;
state->remaining_width = MAX (state->remaining_width, 0);
- insert_run (line, state, item, TRUE);
+ insert_run (line, state, item, TRUE, FALSE);
return BREAK_ALL_FIT;
}
@@ -3694,10 +3700,9 @@ process_item (PangoLayout *layout,
if (break_num_chars == item->num_chars)
{
- gboolean insert_hyphen = break_needs_hyphen (layout, state, break_num_chars);
- insert_run (line, state, item, TRUE);
- if (insert_hyphen)
- insert_hyphen_after (line, state, item);
+ gboolean hyphen;
+ hyphen = break_needs_hyphen (layout, state, break_num_chars);
+ insert_run (line, state, item, TRUE, hyphen);
return BREAK_ALL_FIT;
}
@@ -3708,26 +3713,24 @@ process_item (PangoLayout *layout,
else
{
PangoItem *new_item;
- gboolean insert_hyphen = break_needs_hyphen (layout, state, break_num_chars);
+ gboolean hyphen;
length = g_utf8_offset_to_pointer (layout->text + item->offset, break_num_chars) - (layout->text + item->offset);
new_item = pango_item_split (item, length, break_num_chars);
+ hyphen = break_needs_hyphen (layout, state, break_num_chars);
/* Add the width back, to the line, reshape, subtract the new width */
state->remaining_width += break_width;
- insert_run (line, state, new_item, FALSE);
+ insert_run (line, state, new_item, FALSE, hyphen);
break_width = pango_glyph_string_get_width (((PangoGlyphItem *)(line->runs->data))->glyphs);
state->remaining_width -= break_width;
+ state->log_widths_offset += break_num_chars;
+
/* Shaped items should never be broken */
g_assert (!shape_set);
- if (insert_hyphen)
- insert_hyphen_after (line, state, new_item);
-
- state->log_widths_offset += break_num_chars;
-
return BREAK_SOME_FIT;
}
}