summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-08-25 19:39:43 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-08-25 19:39:43 -0400
commit33cf60ef132fed183964b47973470d0eaf391588 (patch)
tree43e84fa285e75cf1f4ffc9a44e18fac39fe6a40a
parent26b0bee8fd32480b65ee1883416375fc23a041b3 (diff)
downloadpango-33cf60ef132fed183964b47973470d0eaf391588.tar.gz
hyphen: Try harder to insert needed hyphens
We were forgetting to reshape runs in some situations, leading to them not having hyphens appended. This was happening when runs fit fully onto the end of a line that is wrapped anyway.
-rw-r--r--pango/pango-layout.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index ad56e8f9..6b14a5dd 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3671,7 +3671,8 @@ insert_run (PangoLayoutLine *line,
run->item = run_item;
- if (last_run && state->log_widths_offset == 0)
+ if (last_run && state->log_widths_offset == 0 &&
+ !(run_item->analysis.flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN))
run->glyphs = state->glyphs;
else
run->glyphs = shape_run (line, state, run_item);
@@ -5716,8 +5717,47 @@ zero_line_final_space (PangoLayoutLine *line,
{
PangoLayout *layout = line->layout;
PangoItem *item = run->item;
- PangoGlyphString *glyphs = run->glyphs;
- int glyph = item->analysis.level % 2 ? 0 : glyphs->num_glyphs - 1;
+ PangoGlyphString *glyphs;
+ int glyph;
+ int line_chars;
+
+ line_chars = 0;
+ for (GSList *l = line->runs; l; l = l->next)
+ {
+ PangoLayoutRun *r = l->data;
+
+ if (r)
+ line_chars += r->item->num_chars;
+ }
+
+ if (layout->log_attrs[state->line_start_offset + line_chars].break_inserts_hyphen &&
+ !(item->analysis.flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN))
+ {
+ int width;
+ int start_offset;
+
+ /* The last run fit onto the line without breaking it, but it still needs a hyphen */
+
+ width = pango_glyph_string_get_width (run->glyphs);
+
+ /* Ugly, shape_run uses state->start_offset, so temporarily rewind things
+ * to the state before the run was inserted. Otherwise, we end up passing
+ * the wrong log attrs to the shaping machinery.
+ */
+ start_offset = state->start_offset;
+ state->start_offset = state->line_start_offset + line_chars - item->num_chars;
+
+ pango_glyph_string_free (run->glyphs);
+ item->analysis.flags |= PANGO_ANALYSIS_FLAG_NEED_HYPHEN;
+ run->glyphs = shape_run (line, state, item);
+
+ state->start_offset = start_offset;
+
+ state->remaining_width += pango_glyph_string_get_width (run->glyphs) - width;
+ }
+
+ glyphs = run->glyphs;
+ glyph = item->analysis.level % 2 ? 0 : glyphs->num_glyphs - 1;
if (glyphs->glyphs[glyph].glyph == PANGO_GET_UNKNOWN_GLYPH (0x2028))
return; /* this LS is visible */
@@ -5725,7 +5765,6 @@ zero_line_final_space (PangoLayoutLine *line,
/* if the final char of line forms a cluster, and it's
* a whitespace char, zero its glyph's width as it's been wrapped
*/
-
if (glyphs->num_glyphs < 1 || state->start_offset == 0 ||
!layout->log_attrs[state->start_offset - 1].is_white)
return;