summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-12-18 19:15:05 -0500
committerMatthias Clasen <mclasen@redhat.com>2021-12-18 22:26:32 -0500
commit8ba9827171379cf7c2db8fe4d9d884907937554f (patch)
tree0e55ba38033864c4718708a6c9cee97325664448
parent3bcc08d389399b917c58bd70f6807c26f643ed32 (diff)
downloadpango-8ba9827171379cf7c2db8fe4d9d884907937554f.tar.gz
layout: Fix a cornercase of line width accounting
We don't collapse space at the very end, so we should count such spaces towards the line width.
-rw-r--r--pango/pango-layout.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index a3f8b552..a133afe6 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3999,7 +3999,8 @@ process_item (PangoLayout *layout,
PangoLayoutLine *line,
ParaBreakState *state,
gboolean force_fit,
- gboolean no_break_at_end)
+ gboolean no_break_at_end,
+ gboolean is_last_item)
{
PangoItem *item = state->items->data;
gboolean shape_set = FALSE;
@@ -4214,9 +4215,10 @@ retry_break:
new_break_width = pango_glyph_string_get_width (glyphs) + tab_width_change (state);
if (num_chars > 0 &&
+ (item != new_item || !is_last_item) && /* We don't collapse space at the very end */
layout->log_attrs[state->start_offset + num_chars - 1].is_white)
extra_width = - state->log_widths[state->log_widths_offset + num_chars - 1];
- else if (item == new_item &&
+ else if (item == new_item && !is_last_item &&
break_needs_hyphen (layout, state, num_chars))
extra_width = state->hyphen_width;
else
@@ -4486,18 +4488,20 @@ process_line (PangoLayout *layout,
int old_num_chars;
int old_remaining_width;
gboolean first_item_in_line;
+ gboolean last_item_in_line;
old_num_chars = item->num_chars;
old_remaining_width = state->remaining_width;
- first_item_in_line = line->runs != NULL;
+ first_item_in_line = line->runs == NULL;
+ last_item_in_line = state->items->next == NULL;
- result = process_item (layout, line, state, !have_break, FALSE);
+ result = process_item (layout, line, state, !have_break, FALSE, last_item_in_line);
switch (result)
{
case BREAK_ALL_FIT:
if (layout->text[item->offset] != '\t' &&
- can_break_in (layout, state->start_offset, old_num_chars, first_item_in_line))
+ can_break_in (layout, state->start_offset, old_num_chars, !first_item_in_line))
{
have_break = TRUE;
break_remaining_width = old_remaining_width;
@@ -4541,12 +4545,13 @@ process_line (PangoLayout *layout,
state->start_offset = break_start_offset;
state->remaining_width = break_remaining_width;
+ last_item_in_line = state->items->next == NULL;
/* Reshape run to break */
item = state->items->data;
old_num_chars = item->num_chars;
- result = process_item (layout, line, state, TRUE, TRUE);
+ result = process_item (layout, line, state, TRUE, TRUE, last_item_in_line);
g_assert (result == BREAK_SOME_FIT || result == BREAK_EMPTY_FIT);
state->start_offset += old_num_chars - item->num_chars;
@@ -4557,8 +4562,7 @@ process_line (PangoLayout *layout,
case BREAK_LINE_SEPARATOR:
state->items = g_list_delete_link (state->items, state->items);
state->start_offset += old_num_chars;
- /* A line-separate is just a forced break. Set wrapped, so we do
- * justification */
+ /* A line-separate is just a forced break. Set wrapped, so we do justification */
wrapped = TRUE;
goto done;