[balsa/74-quote-wrapped-lines] mime: Use Pango to find line-break positions
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/74-quote-wrapped-lines] mime: Use Pango to find line-break positions
- Date: Wed, 13 Apr 2022 21:27:55 +0000 (UTC)
commit 8609195d98130ebd7adb3bf5442e917135b2288b
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Wed Apr 13 16:49:19 2022 -0400
mime: Use Pango to find line-break positions
In libbalsa_wrap_quoted_string(), use PangoLogAttr to find possible
places to break a long line, instead of literal space characters.
This has the side effect of leaving trailing white space on the wrapped
lines, not included in the line length calculation. If the text is
copy/pasted into a file, it can be unwrapped to something like the
original. The trailing spaces could be trimmed, but it doesn't seem
worthwhile.
libbalsa/mime.c | 56 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 32 insertions(+), 24 deletions(-)
---
diff --git a/libbalsa/mime.c b/libbalsa/mime.c
index 8d6d5f353..2914c145f 100644
--- a/libbalsa/mime.c
+++ b/libbalsa/mime.c
@@ -1316,6 +1316,7 @@ libbalsa_wrap_quoted_string(const char *str,
char **lines;
char **line;
GString *wrapped;
+ PangoLogAttr *log_attrs = NULL;
g_return_val_if_fail(str != NULL, NULL);
g_return_val_if_fail(quote_regex != NULL, NULL);
@@ -1325,52 +1326,59 @@ libbalsa_wrap_quoted_string(const char *str,
for (line = lines; *line != NULL; line++) {
unsigned quote_len, quote_len_utf8;
- const char *start_pos, *space_pos, *ptr;
+ const char *start_ptr, *break_ptr, *ptr;
const unsigned minl = width / 2;
- unsigned te = 0; /* tabs' extra space */
- unsigned ptr_offset, line_begin_offset, space_pos_offset;
+ unsigned ptr_offset, start_offset, break_offset;
+ int num_chars;
+ int attrs_len;
+ unsigned cursor;
+
+ num_chars = g_utf8_strlen(*line, -1);
+ attrs_len = num_chars + 1;
+ log_attrs = g_renew(PangoLogAttr, log_attrs, attrs_len);
+ pango_get_log_attrs(*line, -1, -1, pango_language_get_default(), log_attrs, attrs_len);
libbalsa_match_regex(*line, quote_regex, NULL, "e_len);
g_string_append_len(wrapped, *line, quote_len);
ptr = *line + quote_len;
- quote_len_utf8 = g_utf8_pointer_to_offset(*line, ptr);
- ptr_offset = quote_len_utf8;
+ ptr_offset = g_utf8_pointer_to_offset(*line, ptr);
+ cursor = quote_len_utf8 = ptr_offset;
- line_begin_offset = space_pos_offset = 0;
- start_pos = space_pos = ptr;
+ start_ptr = break_ptr = ptr;
+ start_offset = break_offset = ptr_offset;
while (*ptr != '\0') {
- switch (*ptr) {
- case '\t':
- te += 7;
- break;
- case ' ':
- space_pos = ptr;
- space_pos_offset = ptr_offset;
- break;
+ gunichar c = g_utf8_get_char(ptr);
+
+ if (c == '\t')
+ cursor = ((cursor + 8) / 8) * 8;
+ else
+ cursor++;
+
+ if (log_attrs[ptr_offset].is_line_break) {
+ break_ptr = ptr;
+ break_offset = ptr_offset;
}
- if (ptr_offset - line_begin_offset >= width - te &&
- space_pos_offset >= line_begin_offset + minl) {
- g_string_append_len(wrapped, start_pos, space_pos - start_pos);
+ if (cursor >= width && break_offset >= start_offset + minl && !g_unichar_isspace(c)) {
+ g_string_append_len(wrapped, start_ptr, break_ptr - start_ptr);
g_string_append_c(wrapped, '\n');
-
g_string_append_len(wrapped, *line, quote_len);
- ptr_offset += quote_len_utf8;
- start_pos = space_pos + 1;
- line_begin_offset = space_pos_offset + 1;
- te = 0;
+ start_ptr = break_ptr;
+ start_offset = break_offset;
+ cursor = quote_len_utf8 + ptr_offset - start_offset;
}
ptr = g_utf8_next_char(ptr);
ptr_offset++;
}
- g_string_append(wrapped, start_pos);
+ g_string_append(wrapped, start_ptr);
g_string_append_c(wrapped, '\n');
}
+ g_free(log_attrs);
g_strfreev(lines);
return (char *) g_string_free(wrapped, FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]