Much simplify SGR sequence handling and fix width weirdness

This commit is contained in:
Jacob 2023-07-16 16:35:25 +02:00
parent 15fcdb0ca5
commit e202b1668a
2 changed files with 60 additions and 29 deletions

View file

@ -40,10 +40,41 @@ void drawhighlights(struct item *item, int x, int y, int w, int p, const char *i
}
}
char* get_text_n_sgr(struct item *item) {
char buffer[MAXITEMLENGTH];
int character, escape;
char *sgrtext = malloc(sizeof(buffer));
sgrtext[0] = '\0';
for (character = 0, escape = 0; item->text[escape]; escape++) {
if (item->text[escape] == '' && item->text[escape + 1] == '[') {
size_t colindex = strspn(item->text + escape + 2, "0123456789;");
if (item->text[escape + colindex + 2] == 'm' && sgr) { // last character in sequence is always 'm'
buffer[character] = '\0';
strcat(sgrtext, buffer);
escape += colindex + 2;
character = 0;
continue;
}
}
buffer[character++] = item->text[escape];
}
buffer[character] = '\0';
strcat(sgrtext, buffer);
return sgrtext;
}
int drawitemtext(struct item *item, int x, int y, int w) {
char buffer[MAXITEMLENGTH]; // buffer containing item text
int character, escape;
int leftpadding = sp.lrpad / 2; // padding
int wr, rd; // character
int fg = 7; // foreground
int bg = 0; // background
int bgfg = 0; // both
@ -157,38 +188,31 @@ int drawitemtext(struct item *item, int x, int y, int w) {
ox = x;
oy = y;
ow = w;
item->nsgrtext = malloc(sizeof(buffer));
item->nsgrtext[0] = '\0';
int width = 0;
// parse item text
for (wr = 0, rd = 0; item->text[rd]; rd++) {
if (item->text[rd] == '' && item->text[rd + 1] == '[') {
size_t alen = strspn(item->text + rd + 2, "0123456789;");
if (item->text[rd + alen + 2] == 'm' && sgr) { // last character in sequence is always 'm'
buffer[wr] = '\0';
if (!lines) {
w -= item->text[rd + alen];
}
for (character = 0, escape = 0; item->text[escape]; escape++) {
if (item->text[escape] == '' && item->text[escape + 1] == '[') {
size_t colindex = strspn(item->text + escape + 2, "0123456789;");
if (item->text[escape + colindex + 2] == 'm' && sgr) { // last character in sequence is always 'm'
buffer[character] = '\0';
apply_fribidi(buffer);
draw_text(draw, x, y, MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding, sp.bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
strcat(item->nsgrtext, buffer);
draw_text(draw, x, y, w, sp.bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
// position and width
x += MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding;
w -= MIN(w, TEXTW(buffer) - sp.lrpad) + leftpadding;
x += MIN(w, TEXTW(buffer) - sp.lrpad + leftpadding);
width += MIN(w, TEXTW(buffer) - sp.lrpad + leftpadding);
w -= MIN(w, TEXTW(buffer) - sp.lrpad + leftpadding);
// no highlighting if colored text
leftpadding = 0;
char *character = item->text + rd + 1; // current character
char *c_character = item->text + escape + 1; // current character
// parse hex colors, m is always the last character
while (*character != 'm') {
unsigned nextchar = strtoul(character + 1, &character, 10);
while (*c_character != 'm') {
unsigned nextchar = strtoul(c_character + 1, &c_character, 10);
if (ignore)
continue;
if (bgfg) {
@ -230,18 +254,17 @@ int drawitemtext(struct item *item, int x, int y, int w) {
}
}
rd += alen + 2;
wr = 0;
escape += colindex + 2;
character = 0;
continue;
}
}
buffer[wr++] = item->text[rd];
buffer[character++] = item->text[escape];
}
buffer[wr] = '\0';
strcat(item->nsgrtext, buffer);
buffer[character] = '\0';
// now draw any non-colored text
apply_fribidi(buffer);
@ -307,6 +330,8 @@ int drawitem(int x, int y, int w) {
itemn = 0;
for (item = currentitem; item != nextitem; item = item->right, i++) {
item->nsgrtext = get_text_n_sgr(item);
x = drawitemtext(
item,
rx + menumarginh + ((i / lines) * ((sp.mw - rx) / columns)) + (powerlineitems ? sp.plw : 0),
@ -335,7 +360,9 @@ int drawitem(int x, int y, int w) {
int itemoverride = 1;
for (item = currentitem; item != nextitem; item = item->right) { // draw items
x = drawitemtext(item, x + (powerlineitems ? 2 * sp.plw : 0), y, MIN(pango_item ? TEXTWM(item->text) : TEXTW(item->text),
item->nsgrtext = get_text_n_sgr(item);
x = drawitemtext(item, x + (powerlineitems ? 2 * sp.plw : 0), y, MIN(pango_item ? TEXTWM(item->nsgrtext) : TEXTW(item->nsgrtext),
sp.mw - x -
rarroww -
numberw -

View file

@ -384,13 +384,17 @@ void calcoffsets(void) {
// calculate which items will begin the next page
for (i = 0, nextitem = currentitem; nextitem; nextitem = nextitem->right) {
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(nextitem->text) + (powerlineitems ? !lines ? 3 * sp.plw : 0 : 0), offset)) > offset)
nextitem->nsgrtext = get_text_n_sgr(nextitem);
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(nextitem->nsgrtext) + (powerlineitems ? !lines ? 3 * sp.plw : 0 : 0), offset)) > offset)
break;
}
// calculate which items will begin the previous page
for (i = 0, previousitem = currentitem; previousitem && previousitem->left; previousitem = previousitem->left) {
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(previousitem->left->text) + (powerlineitems ? !lines ? 3 * sp.plw : 0 : 0), offset)) > offset)
previousitem->nsgrtext = get_text_n_sgr(previousitem);
if ((i += (lines > 0) ? sp.bh : MIN(TEXTWM(previousitem->left->nsgrtext) + (powerlineitems ? !lines ? 3 * sp.plw : 0 : 0), offset)) > offset)
break;
}
}