summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/main.c b/main.c
index 7be5539..728db38 100644
--- a/main.c
+++ b/main.c
@@ -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;
}
}