[pango/avoid-overlong-lines: 6/6] Try harder to not produce overlong lines
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/avoid-overlong-lines: 6/6] Try harder to not produce overlong lines
- Date: Fri, 12 Nov 2021 01:01:29 +0000 (UTC)
commit cc60ad4cb7bceef90f6d90930df294abee73d33a
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Nov 11 19:58:21 2021 -0500
Try harder to not produce overlong lines
Our accounting for run lengths is imperfect (mainly
due to log widths for clusters being evenly distributed),
so it can happen that after reshaping the split item,
we find that it does not actually fit in the remaining
width. Previously, we would just use the split run
at that point and produce an overlong line. Instead,
undo the split, disable the breakpoint we used, and
try again.
pango/pango-layout.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
---
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 35e9ba62..57534492 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3525,6 +3525,29 @@ shape_tab (PangoLayoutLine *line,
}
}
+#define DISABLE_BREAKPOINT_FLAG (1 << 16)
+
+static inline void
+disable_breakpoint (PangoLayout *layout,
+ int offset)
+{
+ layout->log_attrs[offset].reserved |= DISABLE_BREAKPOINT_FLAG;
+}
+
+static inline gboolean
+breakpoint_is_disabled (PangoLayout *layout,
+ int offset)
+{
+ return (layout->log_attrs[offset].reserved & DISABLE_BREAKPOINT_FLAG) != 0;
+}
+
+static void
+clear_breakpoint_flags (PangoLayout *layout)
+{
+ for (int i = 0; i < layout->n_chars + 1; i++)
+ layout->log_attrs[i].reserved = 0;
+}
+
static inline gboolean
can_break_at (PangoLayout *layout,
gint offset,
@@ -3542,6 +3565,8 @@ can_break_at (PangoLayout *layout,
if (offset == layout->n_chars)
return TRUE;
+ else if (breakpoint_is_disabled (layout, offset))
+ return FALSE;
else if (wrap == PANGO_WRAP_WORD)
return layout->log_attrs[offset].is_line_break;
else if (wrap == PANGO_WRAP_CHAR)
@@ -3990,7 +4015,27 @@ process_item (PangoLayout *layout,
/* Add the width back, to the line, reshape, subtract the new width */
state->remaining_width += break_width;
insert_run (line, state, new_item, FALSE);
+
break_width = pango_glyph_string_get_width (((PangoGlyphItem *)(line->runs->data))->glyphs);
+ if (break_width > state->remaining_width &&
+ !breakpoint_is_disabled (layout, break_num_chars))
+ {
+ /* Unsplit the item, disable the breakpoint, try again */
+
+ uninsert_run (line);
+ pango_item_free (new_item);
+ pango_item_unsplit (item, length, break_num_chars);
+
+ disable_breakpoint (layout, break_num_chars);
+
+ num_chars = item->num_chars;
+ width = orig_width;
+ break_num_chars = num_chars;
+ break_width = width;
+
+ goto retry_break;
+ }
+
state->remaining_width -= break_width;
state->log_widths_offset += break_num_chars;
@@ -4598,6 +4643,8 @@ pango_layout_check_lines (PangoLayout *layout)
}
while (!done);
+ clear_breakpoint_flags (layout);
+
g_free (state.log_widths);
g_list_free_full (state.baseline_shifts, g_free);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]