Refactor UTF-8 chopping

Add a function that makes sure a string does not exceed a given display
size. If the string is too long, dots ("...") are appended.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
Lukas Fleischer 2016-02-25 21:48:39 +01:00
parent 85772d746f
commit c34f9aba29
4 changed files with 36 additions and 21 deletions

View File

@ -1090,6 +1090,7 @@ void ui_todo_set_view(int);
/* utf8.c */
int utf8_width(char *);
int utf8_strwidth(char *);
int utf8_chop(char *, int);
/* utils.c */
void exit_calcurse(int) __attribute__ ((__noreturn__));

View File

@ -427,7 +427,6 @@ day_display_item(struct day_item *day, WINDOW *win, int incolor, int width,
{
int ch_recur, ch_note;
char buf[width * UTF8_MAXLEN];
int i;
if (width <= 0)
return;
@ -437,23 +436,15 @@ day_display_item(struct day_item *day, WINDOW *win, int incolor, int width,
ch_recur = (day->type == RECUR_EVNT
|| day->type == RECUR_APPT) ? '*' : ' ';
ch_note = day_item_get_note(day) ? '>' : ' ';
if (incolor == 0)
strncpy(buf, mesg, width * UTF8_MAXLEN);
buf[sizeof(buf) - 1] = '\0';
utf8_chop(buf, width - 3);
if (!incolor)
custom_apply_attr(win, ATTR_HIGHEST);
if (utf8_strwidth(mesg) < width) {
mvwprintw(win, y, x, " %c%c%s", ch_recur, ch_note, mesg);
} else {
for (i = 0; mesg[i] && width > 0; i++) {
if (!UTF8_ISCONT(mesg[i]))
width -= utf8_width(&mesg[i]);
buf[i] = mesg[i];
}
if (i)
buf[i - 1] = 0;
else
buf[0] = 0;
mvwprintw(win, y, x, " %c%c%s...", ch_recur, ch_note, buf);
}
if (incolor == 0)
mvwprintw(win, y, x, " %c%c%s", ch_recur, ch_note, buf);
if (!incolor)
custom_remove_attr(win, ATTR_HIGHEST);
}

View File

@ -875,17 +875,17 @@ void ui_day_draw(int n, WINDOW *win, int y, int hilt, void *cb_data)
struct date slctd_date = *ui_calendar_get_slctd_day();
time_t date = date2sec(slctd_date, 0, 0);
struct day_item *item = day_get_item(n);
int width = lb_apt.sw.w;
int width = lb_apt.sw.w - 2;
hilt = hilt && (wins_slctd() == APP);
if (item->type == EVNT || item->type == RECUR_EVNT) {
day_display_item(item, win, !hilt, width, y, 1);
day_display_item(item, win, !hilt, width - 1, y, 1);
} else if (item->type == APPT || item->type == RECUR_APPT) {
day_display_item_date(item, win, !hilt, date, y, 1);
day_display_item(item, win, !hilt, width, y + 1, 1);
day_display_item(item, win, !hilt, width - 1, y + 1, 1);
} else if (item->type == DAY_HEADING) {
unsigned x = width - (strlen(_(monthnames[slctd_date.mm - 1])) + 17);
unsigned x = width - (strlen(_(monthnames[slctd_date.mm - 1])) + 15);
custom_apply_attr(win, ATTR_HIGHEST);
mvwprintw(win, y, x, "%s %s %02d, %04d",
ui_calendar_get_pom(date),

View File

@ -336,3 +336,26 @@ int utf8_strwidth(char *s)
return width;
}
/* Trim a UTF-8 string if it is too long, possibly adding dots for padding. */
int utf8_chop(char *s, int width)
{
int i, n = 0;
for (i = 0; s[i] && width > 0; i++) {
if (!UTF8_ISCONT(s[i]))
width -= utf8_width(&s[i]);
if (width >= 3)
n = i + 1;
}
if (s[i] == '\0')
return 0;
if (s[n] != '\0' && s[n + 1] != '\0' && s[n + 2] != '\0') {
s[n] = s[n + 1] = s[n + 2] = '.';
s[n + 3] = '\0';
}
return 1;
}