[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 20:55:54 +0000 (UTC)
commit 5257155e19f710ffaccb8dc2c22f135ef7679232
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, which is 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 would still be
counted toward the line length, so 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..3d39c4594 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_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]