diff options
author | wrmr | 2025-08-24 19:59:42 -0400 |
---|---|---|
committer | wrmr | 2025-08-24 19:59:42 -0400 |
commit | 8298a7dbc7d0186a80ca02b23c41a4ef2984fb1c (patch) | |
tree | 24b4018eb95f6891827623cc35e51a9b95770b32 | |
parent | dbb6fe40c751705c47360e2417f5151c67563040 (diff) |
better pfps
-rw-r--r-- | main.c | 72 |
1 files changed, 48 insertions, 24 deletions
@@ -16,6 +16,7 @@ #include <stdio.h> #include <locale.h> +#include <stdbit.h> #include <stdlib.h> #include <dirent.h> #include <curses.h> @@ -44,6 +45,9 @@ #define GFX_TEXT_MARGIN_Y 0 #define GFX_POST_SPACING 1 +#define PFP_LINES 3 +#define PFP_COLS 7 + /* colors */ #define CPAIR_INIT_X(cp, fg, bg) init_pair(cp, fg, bg); @@ -104,7 +108,7 @@ regex_t re_mention; Options opt = { .pfp_vis = 1, .margin = { - .left = 8, + .left = 0, .right = 0 } }; @@ -178,7 +182,7 @@ int timestamp_invalid(struct timespec *ts) { typedef struct { int lines, cols; - Str *txt; + Str *line; } Pfp; typedef struct { @@ -186,19 +190,33 @@ typedef struct { Pfp pfp; } User; -/* TODO: utf8 support */ +int fast_utf8_width(Str s) { + int n = 0; + for (int i = 0; i < s.n; i++) { + if (stdc_leading_ones(i) > 0) { + i += stdc_leading_ones(i) - 1; + } + n++; + } + return n; +} + void pfp_load(Pfp *pfp, Str src, Arena *a) { int lines = 0, cols = 0; for (Str s = src, l = {0}; next_line(&s, &l);) { - if (l.n > cols) cols = l.n; + int w = fast_utf8_width(l); + if (w > cols) cols = w; lines++; } - pfp->lines = lines; - pfp->cols = cols; - pfp->txt = new_arr(a, Str, lines); + pfp->lines = lines > PFP_LINES ? lines : PFP_LINES; + pfp->cols = cols > PFP_COLS ? cols : PFP_COLS; + pfp->line = new_arr(a, Str, pfp->lines); lines = 0; for (Str s = src, l = {0}; next_line(&s, &l);) { - pfp->txt[lines++] = l; + pfp->line[lines++] = l; + } + while (lines < pfp->lines) { + pfp->line[lines++] = S(""); } } @@ -392,12 +410,18 @@ typedef struct { GfxPost *posts; } Gfx; -int gfx_post_width(void) { - return getmaxx(stdscr) - GFX_MARGIN_X * 2 - opt.margin.left - opt.margin.right; +int post_left_margin(Post *post) { + int lm = opt.margin.left; + if (post->user->pfp.cols > lm) lm = post->user->pfp.cols; + return lm; } -int gfx_wrap_width(void) { - return gfx_post_width() - GFX_TEXT_MARGIN_X * 2; +int gfx_post_width(Post *post) { + return getmaxx(stdscr) - GFX_MARGIN_X * 2 - post_left_margin(post) - opt.margin.right; +} + +int gfx_wrap_width(Post *post) { + return gfx_post_width(post) - GFX_TEXT_MARGIN_X * 2; } void gfx_load_post(GfxPost *post, Post *src, int width, Arena *a) { @@ -410,11 +434,10 @@ void gfx_load_post(GfxPost *post, Post *src, int width, Arena *a) { } void gfx_load(Gfx *gfx, PostList *posts, Arena *a) { - int width = gfx_wrap_width(); gfx->len = posts->len; gfx->posts = new_arr(a, GfxPost, gfx->len); for (int i = 0; i < gfx->len; i++) { - gfx_load_post(&gfx->posts[i], &posts->data[i], width, a); + gfx_load_post(&gfx->posts[i], &posts->data[i], gfx_wrap_width(&posts->data[i]), a); } } @@ -431,7 +454,9 @@ void gfx_predraw_post(GfxPost *post) { } int gfx_post_height(GfxPost *post) { - return post->lines + 2 + GFX_TEXT_MARGIN_Y * 2; + int n = 0; + if (post->src->user->pfp.lines > post->lines + 2) n = post->src->user->pfp.lines - post->lines - 2; + return post->lines + 2 + GFX_TEXT_MARGIN_Y * 2 + n; } void gfx_draw_post(GfxPost *post, int y, int x, int width) { @@ -442,7 +467,7 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) { post->drawn = 1; } - int left = x + opt.margin.left, top = y + opt.margin.top; + int left = x + post_left_margin(post->src), top = y + opt.margin.top; int right = left + width - 1, bottom = top + height - 1; int self = is_post_mine(post->src); @@ -463,12 +488,12 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) { if (opt.pfp_vis) { color_set(self ? CPAIR_PFP_SELF : CPAIR_PFP, 0); - User *u = post->src->user; - if (u) { - Pfp *pfp = &u->pfp; - for (int i = 0; i < pfp->lines; i++) { - mvaddnstr(top + i + GFX_TEXT_MARGIN_Y, left - pfp->cols - GFX_TEXT_MARGIN_X, pfp->txt[i].s, pfp->txt[i].n); - } + Pfp *pfp = &post->src->user->pfp; + int pfptop = top + GFX_TEXT_MARGIN_Y; + if (height > pfp->lines) pfptop += (height - pfp->lines) >> 1; + int pfpleft = left - pfp->cols - GFX_TEXT_MARGIN_X; + for (int i = 0; i < pfp->lines; i++) { + mvaddnstr(pfptop + i, pfpleft, pfp->line[i].s, pfp->line[i].n); } } @@ -486,10 +511,9 @@ void gfx_draw_post(GfxPost *post, int y, int x, int width) { } void gfx_draw(Gfx *gfx, int cur) { - int width = gfx_post_width(); erase(); for (int i = cur, y = GFX_MARGIN_Y; i < gfx->len && y < getmaxy(stdscr) - GFX_MARGIN_Y; i++) { - gfx_draw_post(&gfx->posts[i], y, GFX_MARGIN_X, width); + gfx_draw_post(&gfx->posts[i], y, GFX_MARGIN_X, gfx_post_width(gfx->posts[i].src)); y += gfx_post_height(&gfx->posts[i]) + GFX_POST_SPACING; } } |