poe

Уређивач .po фајлова
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување b39e5e9e8e2aefcb6118893e8cda089c01b2e6c0
родитељ 4124504b05c76685589802362d58ba3095d65c93
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Fri,  9 Jul 2021 13:43:50 +0200

Finished work on u32_draw_string wrt tabs

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
Mdraw.c | 270++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mdraw.h | 4++--
Mpoe.c | 14+++++++-------
Mtabs.draft | 108+++++++++++++++++++++----------------------------------------------------------
Mutil.h | 1+
измењених датотека: 5, додавања: 195(+), брисања: 202(-)

diff --git a/draw.c b/draw.c @@ -271,158 +271,200 @@ draw_box(const int startx, const int endx, const int starty, const int endy, tb_change_cell(x, endy-1, ' ', SHADOW_FG, SHADOW_BG); } +/* mc - (max cols) pack text and padding into this many columns + * fc - (fill cols) this many columns from the left/right/center will be + * filled + * p_? - (padding) this many cells will be skipped from ? side + * ds - (display start) string starts being displayed from this display column + * counted from the start of the string; an "entry point" joining string + * index with screen + * fill - boolean; 1 = fill fc, 0 = don't fill fc + * */ const char* draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg, - const char* s, const int max_cols, const int fill_cols, - const int padding_left, const int padding_right, - const Alignment align, const int display_starts_at) + const char* s, const int mc, const int fc, + const int p_l, const int p_r, + const Alignment align, const int ds, const int fill) { uint32_t* us = calloc(strlen(s)+1, sizeof(uint32_t)); if (!us) return NULL; - u8_string_to_unicode(us, s, max_cols); - u32_draw_string(x, y, fg, bg, us, max_cols, fill_cols, - padding_left, padding_right, align, display_starts_at); + u8_string_to_unicode(us, s, mc); + u32_draw_string(x, y, fg, bg, us, mc, fc, p_l, p_r, align, ds, fill); free(us); return s; } -/* mc - pack text and padding into this many columns - * fc - this many columns from the left/right/center will be filled - * p_? - this many cells will be skipped from ? side - * ds - string starts being displayed from this column (will fit into c) */ +/* mc - (max cols) pack text and padding into this many columns + * fc - (fill cols) this many columns from the left/right/center will be + * filled + * p_? - (padding) this many cells will be skipped from ? side + * ds - (display start) string starts being displayed from this display column + * counted from the start of the string; an "entry point" joining string + * index with screen + * fill - boolean; 1 = fill fc, 0 = don't fill fc + * */ void u32_draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg, const uint32_t* s, const int mc, const int fc, const int p_l, const int p_r, - const Alignment align, const int ds) + const Alignment align, const int ds, const int fill) { - int d = 0; /* distance, in screen columns, from x to visible - * part of the string, followed by p_l */ - - int c = 0; /* distance in screen columns from - * d + p_l to mc - p_r (part of the displayed string - * containing text, between padding; - * string fits within this many columns */ - - int r = 0; /* current rune; goes from 0..c */ - - int i = 0; /* string index */ - /* * <-------- visible part ----------> * +---------+-------+----------------+---------+ - * |d=0 | |c=0 | | + * | | | | | * |<-- d -->|<-p_l->|<------ c ----->|<- p_r ->| * | |<-------------- mc -------------->| * |<------------------ fc -------------------->| - * x (align == RIGHT here) + * x | | + * ds ds+c + * <.....(sc).....> + * (align == RIGHT in this case) * */ - const uint32_t* ps = s; - size_t len = u32_strlen(s); + + int d = 0; /* distance, in screen columns, from x to + * visible part of the string, followed by + * p_l */ + + int c = 0; /* distance in screen columns from + * d + p_l to d + mc - p_r (part of the + * displayed string containing text, between + * padding; string fits within this many columns + * */ + + int sc = 0; /* current screen column; goes from 0..c-1 + * only increased when actual characters are + * written + */ + + int ssc = 0; /* current string screen column; goes from start + * of the string until ds+c */ + + const int ts = TAB_SIZE; + + const uint32_t* ps = s; /* pointer to current character in string; + * string index: ps-s */ c = mc - p_l - p_r; + if (align == LEFT) - { d = 0; - for (r = 0; r < fc; r++) /* r wraps p_? here for filling */ - tb_change_cell(x + d + r, y, ' ', fg, bg); - } else if (align == RIGHT) - { - d = fc - mc; - /* r wraps p_? here for filling */ - for (r = 0; r < mc; r++) - tb_change_cell(x + d + r, y, ' ', fg, bg); - } + d = fc >= mc ? fc-mc : 0; else if (align == CENTER) - { - d = (fc - mc)/2; - for (r = 0; r < mc; r++) - tb_change_cell(x + d + r, y, ' ', fg, bg); - } + d = fc >= mc ? (fc - mc)/2 : 0; + + /* fill */ + if (fill) + for (int j = 0; j < fc; j++) + tb_change_cell(x+j, y, ' ', fg, bg); + + /* left padding */ + for (int j = 0; j < p_l; j++) + tb_change_cell(x+d+j, y, ' ', fg, bg); + + sc = 0; - r = 0; - i = 0; - while (ps && *ps && r < c) + /* + * main idea: we go from start of the string to the end and count + * displayed characters until we get to ds, then we also output + * characters; tabs count as spaces up to multiple of ts, counted from + * the start of the string + * + * exit condition is also sc == c, when we have reached the maximum + * number of characters to output + * */ + while (ps && *ps && sc < c) { if (*ps == '\t') { - if (i < ds) + if (ssc < ds) { - /* col+TAB_SIZE - * \t | - * ------[ :::|: ] - * | | c+padding_left=c+2 - * | c - * i + /* ssc-(ssc%ts)+ts + * \t | = ssc+(ts-(ssc%ts)) + * ----------|-----[ :|::: ] + * | | | + * | | ds + * ssc-(ssc%ts) | + * ssc * */ - if () + if (ssc - (ssc % ts) + ts >= ds) { - for (int j = 0; j < ; + for (int j = 0; j < ssc-(ssc%ts)+ts-ds; j++) - tb_change_cell(x+padding_left+ - j, y, ' ', fg, bg); + tb_change_cell(x+d+p_l+sc+j, y, + ' ', fg, bg); + sc += (ts - (ssc % ts)); } - /* + /* else, just increase counter + * * \t * ----------|----[ ::::: ] - * | | | - * | | c - * | col+TAB_SIZE - * col + * | | | + * | | ds + * | ssc-(ssc%ts)+ts + * ssc = ssc + (ts-(ssc%ts)) * */ - col += TAB_SIZE; + ssc += (ts - (ssc % ts)); } - else + else /* ssc >= ds */ { /* - * col+TAB_SIZE = col+end - * \t | + * ds ssc+(ts-(ssc%ts)) + * | \t | * [ ::::::: ]---|----- - * | | - * | dlimit - * col = (col - start) + start + * | | + * | ds+c + * ssc * */ - int dlimit = max_cols-padding_right; - if (col + end >= dlimit) + if (ssc+(ts-(ssc%ts)) >= ds+c) { - int spaces = dlimit - col; - for (int j = 0; j < spaces; j++) - tb_change_cell(x+padding_left+ - col+j, y, ' ', fg, bg); - col += spaces; + for (int j = 0; j < ds+c-ssc; j++) + tb_change_cell(x+d+p_l+sc+j, + y, ' ', fg, bg); + sc = c; + ssc = ds+c; } - /* + else /* ssc+(ts-(ssc%ts)) < ds+c */ + { + /* * \t * [ :::::::::::|::: ]----- - * | | | | - * | | | dlimit - * | | col+TAB_SIZE - * | col - * c + * | | | | + * | | | ds+c + * | | ssc+(ts-(ssc%ts)) + * | ssc + * ds * */ - else - { - for (int j = start; j < end; j++) - tb_change_cell(x+padding_left+ - (col-start)+j, y, ' ', - fg, bg); - col += TAB_SIZE; + for (int j = 0; j < ts-(ssc%ts); j++) + tb_change_cell(x+d+p_l+sc+j, + y, ' ', fg, bg); + sc += ts-(ssc%ts); + ssc += ts-(ssc%ts); } } } else { - if (col >= c) - tb_change_cell(x+padding_left+col-c, y, *ps, - fg, bg); - col++; + if (ssc >= ds) + { + if (sc < c) + tb_change_cell(x+d+p_l+sc, y, *ps, + fg, bg); + sc++; + } + ssc++; } ps++; } + + /* right padding */ + for (int j = 0; j < p_r; j++) + tb_change_cell(x+d+p_l+c+j, y, ' ', fg, bg); + } const struct DrawState* @@ -446,12 +488,13 @@ draw_help(const struct DrawState* state) draw_box(startx, endx, starty, endy, DLG_FG, DLG_BG); if (!draw_string(startx, starty, TITLE_FG, TITLE_BG, - help_title, w-2, strlen(help_title)+2, 1, 1, CENTER, 0)) + help_title, strlen(help_title)+2, w-2, 1, 1, CENTER, + 0, 0)) return NULL; while (row < LEN(help)) { if (!draw_string(startx+1, starty+1+row, DLG_FG, DLG_BG, - help[row], w-2, w-2, 2, 2, LEFT, 0)) + help[row], w-2, w-2, 2, 2, LEFT, 0, 1)) return NULL; row++; } @@ -486,8 +529,8 @@ draw_editbox(const struct DrawState* state) draw_box(startx, endx, starty, endy, DLG_FG, DLG_BG); if (!draw_string(startx+1, starty, TITLE_FG, TITLE_BG, - editbox_title, w-2, - strlen(editbox_title)+2, 1, 1, CENTER, 0)) + editbox_title, strlen(editbox_title)+2, w-2, 1, 1, + CENTER, 0, 0)) return NULL; uint16_t fg = state->edit_info_focused ? EDIT_MSGID_FOCUS_FG : @@ -511,15 +554,15 @@ draw_editbox(const struct DrawState* state) curline->bg == 0 ? bg : curline->bg, curline->text, w-2, w-2, 1, 1, LEFT, - state->info_first_shown_column); + state->info_first_shown_column, 1); } if (state->info_first_shown_row > 0) u32_draw_string(endx-2, starty+1, fg, bg, (uint32_t*)L"\u2191", - 1, 1, 0, 0, LEFT, 0); + 1, 1, 0, 0, LEFT, 0, 0); if (state->info_first_shown_row + (h-3)/2 < state->info_rows_count) u32_draw_string(endx-2, starty+(h-3)/2, fg, bg, - (uint32_t*)L"\u2193", 1, 1, 0, 0, LEFT, 0); + (uint32_t*)L"\u2193", 1, 1, 0, 0, LEFT, 0, 0); fg = state->edit_info_focused ? EDIT_MSGSTR_FG : EDIT_MSGSTR_FOCUS_FG; @@ -540,7 +583,7 @@ draw_editbox(const struct DrawState* state) u32_draw_string(startx+1, endy-h/2-1+i, fg, bg, curline->text, w-2, w-2, 1, 1, LEFT, - state->input_first_shown_column); + state->input_first_shown_column, 1); } if (state->edit_info_focused) @@ -569,11 +612,11 @@ draw_editbox(const struct DrawState* state) state->input_first_shown_row, state->input_rows_count); draw_string(startx+1, endy-2, DLG_FG, DLG_BG, - sbuf, w-2, strlen(sbuf)+2, 1, 1, LEFT, 0); + sbuf, strlen(sbuf)+2, w-2, 1, 1, LEFT, 0, 0); if (entry->flags != FL_NONE) if (!draw_string(endx-MAXFLAGSBUF-4-5, endy-2, DLG_FG, DLG_BG, flags_buf, MAXFLAGSBUF+4-1, MAXFLAGSBUF+4-1, 0, - 0, LEFT, 0)) + 0, LEFT, 0, 0)) return NULL; return state; } @@ -599,9 +642,9 @@ draw_search(const struct DrawState* state) SEARCH_EDIT_BG); if (len > state->search_input_first_shown_column) u32_draw_string(startx+1, starty+1, - SEARCH_EDIT_FG, SEARCH_EDIT_BG, state->search + - state->search_input_first_shown_column, - w-3, w-3, 0, 0, LEFT, state->input_first_shown_column); + SEARCH_EDIT_FG, SEARCH_EDIT_BG, state->search, + w-3, w-3, 0, 0, LEFT, state->input_first_shown_column, + 1); tb_set_cursor(startx+1+state->search_input_display_column - state->search_input_first_shown_column, starty+1); @@ -623,13 +666,13 @@ draw_status(const struct DrawState* state) { if (!draw_string(0, state->maxy-1, PROMPT_FG, PROMPT_BG, state->prompt, state->maxx, state->maxx, 1, 1, - CENTER, 0)) + CENTER, 0, 1)) return NULL; } else if (state->error && state->error[0]) { if (!draw_string(0, state->maxy-1, ERROR_FG, ERROR_BG, state->error, - state->maxx, state->maxx, 1, 1, CENTER, 0)) + state->maxx, state->maxx, 1, 1, CENTER, 0, 1)) return NULL; } else @@ -645,8 +688,9 @@ draw_status(const struct DrawState* state) if (pseg == status_segments + LEN(status_segments)-1) seg_size = state->maxx-1 - current_start; if (!draw_string(current_start, state->maxy-1, pseg->fg, - pseg->bg, buf, seg_size, seg_size, 1, 1, - pseg->alignment, 0)) + pseg->bg, buf, + MIN(seg_size, strlen(buf)+2), seg_size, + 1, 1, pseg->alignment, 0, 1)) return NULL; pseg++; current_start += seg_size; @@ -684,7 +728,7 @@ draw_list_visible(const struct DrawState* state) if (!draw_string(0, cy, sel ? LIST_FLAGS_SEL_FG : LIST_FLAGS_FG, sel ? LIST_FLAGS_SEL_BG : LIST_FLAGS_BG, flags_buf, MAXFLAGSBUF-1+2, MAXFLAGSBUF-1+2, - 2, 0, LEFT, 0)) + 2, 0, LEFT, 0, 1)) return NULL; if (current->msgid) u32_draw_string(MAXFLAGSBUF-1+2, cy, sel ? @@ -693,7 +737,7 @@ draw_list_visible(const struct DrawState* state) current->msgid, state->maxx/2-MAXFLAGSBUF+1-2, state->maxx/2-MAXFLAGSBUF+1-2, 2, 0, - LEFT, 0); + LEFT, 0, 1); else if (current == state->entries) /* special */ draw_string(MAXFLAGSBUF-1+2, cy, sel ? LIST_MSGID_SPECIAL_SEL_FG : @@ -703,7 +747,7 @@ draw_list_visible(const struct DrawState* state) first_entry_msgid, state->maxx/2-MAXFLAGSBUF+1-2, state->maxx/2-MAXFLAGSBUF+1-2, 2, 0, - LEFT, 0); + LEFT, 0, 1); /* don't use msgstr_index as then the entire list will shift * when changing currently displayed plural form msgstr in an @@ -718,7 +762,7 @@ draw_list_visible(const struct DrawState* state) *(current->msgstr /*+ state->msgstr_index*/), state->maxx/2, state->maxx/2, 2, 2, - LEFT, 0); + LEFT, 0, 1); i++; cy++; } diff --git a/draw.h b/draw.h @@ -102,11 +102,11 @@ void draw_box(const int startx, const int endx, const int starty, const char* draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg, const char* s, const int max_cols, const int fill_cols, const int padding_left, const int padding_right, - const Alignment align, const int display_starts_at); + const Alignment align, const int ds, const int fill); void u32_draw_string(const int x, const int y, const uint16_t fg, const uint16_t bg, const uint32_t* s, const int max_cols, const int fill_cols, const int padding_left, const int padding_right, - const Alignment align, const int display_starts_at); + const Alignment align, const int ds, const int fill); const struct DrawState* draw_help(const struct DrawState* state); const struct DrawState* draw_editbox(const struct DrawState* state); const struct DrawState* draw_search(const struct DrawState* state); diff --git a/poe.c b/poe.c @@ -763,10 +763,10 @@ move_up(struct DrawState* state) state->input_display_column); if (state->input_first_shown_column > state->input_display_column) state->input_first_shown_column = state->input_display_column; - if (state->input_first_shown_column + EDIT_WIDTH-5 < + if (state->input_first_shown_column + EDIT_WIDTH-4 < state->input_display_column) state->input_first_shown_column = state->input_display_column - - EDIT_WIDTH+5; + EDIT_WIDTH+4; state->input_display_column = display_length(state, state->input_buffer[state->input_row].text, state->input_column); @@ -803,10 +803,10 @@ move_down(struct DrawState* state) state->input_display_column); if (state->input_first_shown_column > state->input_display_column) state->input_first_shown_column = state->input_display_column; - if (state->input_first_shown_column + EDIT_WIDTH-5 < + if (state->input_first_shown_column + EDIT_WIDTH-4 < state->input_display_column) state->input_first_shown_column = state->input_display_column - - EDIT_WIDTH+5; + EDIT_WIDTH+4; state->input_display_column = display_length(state, state->input_buffer[state->input_row].text, state->input_column); @@ -878,9 +878,9 @@ move_right(struct DrawState* state) state->input_column++; if (state->input_display_column - state->input_first_shown_column - > EDIT_WIDTH-3) + > EDIT_WIDTH-4) state->input_first_shown_column = state->input_display_column - - EDIT_WIDTH+3; + - EDIT_WIDTH+4; } void @@ -901,7 +901,7 @@ move_end(struct DrawState* state) state->input_row].text, state->input_column); state->input_display_column = dlen; if (dlen > EDIT_WIDTH-3) - state->input_first_shown_column = dlen - EDIT_WIDTH+3; + state->input_first_shown_column = dlen - EDIT_WIDTH+4; else state->input_first_shown_column = 0; } diff --git a/tabs.draft b/tabs.draft @@ -1,84 +1,32 @@ - s - string - x - starting column - y - starting row - c - first screen column - t - index in string containing \t - max_cols = w - max screen width - col = d - current screen column - - w = padding_left + ... + padding_right - - -01 234567890123456 7 -f\t test_with_tabs\t; -012[45670123456701234567]123456701234567012345670123456701234567 -f------>test_with_tabs->] -f [----test_with_tabs--] -012[45678901234567890123]567890123456789012345678901234567890123456789 - | - t = 1 -012[45678901234567890123]567890123456789012345678901234567890123456789 - | |<--c+w=24 - c = 4 | - [01234567890123456789]1234567890123456789012345678901234567890123456789 - | - w = 20 ------------------------|<--c+w=24 - -int i = 0; -int d = 0; -while (i < len && d < c+w) -{ - if (s[i] == '\t') - { - if (d < c) - { - if (d+8 >= c) - for (int j = 0; j < 8-(c-d); j++) - print(' '); - d += 8; - } - else - { - for (int j = 0; j < MIN(c+w-d, 8); j++) - print(' '); - d += MIN(c+w-d, 8); - } - } - else - { - if (d >= c) - print(s[i]); - d++; - } - - i++; -} - - ABC\t WQ - A - |B - ||C - |||\t - 0123 45 - c - | - 01234567890123456789 - [ - ABC.::::WQ - [ | ----+----+ | - | | | - x x+padding_left - | | - | c=4 - c=0 - -c = 0..n -draw(x+padding_left+c) - - + | | + |012345678901234567890123456789|123456789 + |012345670123456701234567012345|701234567 + ds = 0 |The quick brown fox | jumps. + i = 19 | |----|-> + *ps = '\t' + + | | + 0|234567890123456789012345678901|3456789 + 0|234567012345670123456701234567|1234567 + T|e quick brown fox |umps. + | |-> + ds = 2 ds = first shown display column + i = 20 + *ps = 'j' + + | | + 0123|567890123456789012345678901234|6789 + 0123|567012345670123456701234567012|4567 + The | quick brown fox jum|s. + | | + ds = 5 | | + i = 23 + *ps = 'p' + + + + diff --git a/util.h b/util.h @@ -1,5 +1,6 @@ #include <bits/stdint-uintn.h> #include <sys/types.h> +#define ABS(a) ((a < 0) ? (-a) : (a)) #define LEN(x) (sizeof(x) / sizeof(x[0])) #define MAX(a,b) ((a > b) ? a : b) #define MIN(a,b) ((a < b) ? a : b)