💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › 97c771a7d02bd76b734f4fdffda1d… captured on 2024-02-05 at 10:00:18. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-12-28)
-=-=-=-=-=-=-
0 /*
1 * ISC License
2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
3 */
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include "macro.h"
9 #include "wcwidth.h"
10 #define PAGE_INTERNAL
11 #include "page.h"
12 #include "request.h"
13 #include "parser.h"
14
15 static int newline(struct termwriter *termwriter) {
16 struct page_cell cell = {0};
17 cell.special = PAGE_NEWLINE;
18 termwriter->sent++;
19 termwriter->last_x = 0;
20 return write(termwriter->fd, P(cell)) != sizeof(cell);
21 }
22
23 int writecell(struct termwriter *termwriter, struct page_cell cell,
24 size_t pos) {
25
26 size_t i, x, nextspace;
27 size_t last_reset; /* bytes since last reset cell */
28
29 /* flush last cells before sending EOF */
30 if (cell.special == PAGE_EOF) {
31 writenewline(termwriter, termwriter->pos);
32 write(termwriter->fd, P(cell));
33 return 0;
34 }
35
36 last_reset = termwriter->sent - termwriter->last_reset;
37 if (termwriter->sent && last_reset >= PARSER_CHUNK / 2) {
38 struct page_cell cell = {0};
39 cell.special = PAGE_RESET;
40 cell.codepoint = pos;
41 cell.link = termwriter->sent++;
42 termwriter->last_reset = termwriter->sent;
43 write(termwriter->fd, P(cell));
44 }
45
46 if (cell.codepoint == '\n') {
47 memset(&cell, 0, sizeof(cell));
48 cell.special = PAGE_NEWLINE;
49 }
50
51 if (cell.special == PAGE_BLANK) {
52 termwriter->sent++;
53 return write(termwriter->fd, P(cell)) != sizeof(cell);
54 }
55 if (!cell.special && termwriter->pos < LENGTH(termwriter->cells)) {
56 termwriter->cells[termwriter->pos] = cell;
57 termwriter->pos++;
58 return 0;
59 }
60 nextspace = 0;
61 x = termwriter->last_x;
62 for (i = 0; i < termwriter->pos; i++) {
63 if (i >= nextspace) {
64 size_t j, nextspace_x;
65 nextspace_x = x;
66 for (j = i + 1; j < termwriter->pos; j++) {
67 nextspace_x += termwriter->cells[j].width;
68 if (termwriter->cells[j].codepoint == '-') {
69 j++;
70 break;
71 }
72 if (WHITESPACE(termwriter->cells[j].codepoint))
73 break;
74 }
75 if (nextspace_x - x <= termwriter->width &&
76 nextspace_x >= termwriter->width) {
77 newline(termwriter);
78 x = 0;
79 nextspace = i;
80 if (WHITESPACE(termwriter->cells[j].codepoint))
81 continue;
82 }
83 nextspace = j;
84 }
85 if (termwriter->cells[i].codepoint == '\t') {
86 termwriter->cells[i].width = TAB_SIZE - (x % TAB_SIZE);
87 termwriter->cells[i].codepoint = ' ';
88 }
89 x += termwriter->cells[i].width;
90 termwriter->sent++;
91 if (write(termwriter->fd, P(termwriter->cells[i])) !=
92 sizeof(cell))
93 return -1;
94 if (x >= termwriter->width) {
95 newline(termwriter);
96 x = 0;
97 }
98 }
99 if (cell.special == PAGE_NEWLINE) x = 0;
100 else x += cell.width;
101 termwriter->last_x = x;
102 termwriter->pos = 0;
103 termwriter->sent++;
104 return -(write(termwriter->fd, P(cell)) != sizeof(cell));
105 }
106
107 int writenewline(struct termwriter *termwriter, size_t pos) {
108 struct page_cell newline = {0};
109 newline.special = PAGE_NEWLINE;
110 return writecell(termwriter, newline, pos);
111 }
112
113 int writeto(struct termwriter *termwriter, const char *str,
114 int color, int link, size_t pos) {
115 const char *ptr = str;
116 while (*ptr) {
117 struct page_cell cell = {0};
118 cell.codepoint = *ptr;
119 cell.link = link;
120 cell.width = mk_wcwidth(cell.codepoint);
121 cell.color = color;
122 if (writecell(termwriter, cell, pos)) return -1;
123 ptr++;
124 }
125 return 0;
126 }
127