📄 html_r.c
字号:
#include "links.h"static inline int color_distance(struct rgb *c1, struct rgb *c2){ return 3 * (c1->r - c2->r) * (c1->r - c2->r) + 4 * (c1->g - c2->g) * (c1->g - c2->g) + 2 * (c1->b - c2->b) * (c1->b - c2->b);}struct rgb palette[] = {/* {0x00, 0x00, 0x00, 0}, {0x80, 0x00, 0x00, 0}, {0x00, 0x80, 0x00, 0}, {0x80, 0x80, 0x00, 0}, {0x00, 0x00, 0x80, 0}, {0x80, 0x00, 0x80, 0}, {0x00, 0x80, 0x80, 0}, {0xC0, 0xC0, 0xC0, 0}, {0x80, 0x80, 0x80, 0}, {0xff, 0x00, 0x00, 0}, {0x00, 0xff, 0x00, 0}, {0xff, 0xff, 0x00, 0}, {0x00, 0x00, 0xff, 0}, {0xff, 0x00, 0xff, 0}, {0x00, 0xff, 0xff, 0}, {0xff, 0xff, 0xff, 0},*/ /*{0x00, 0x00, 0x00, 0}, {0xaa, 0x00, 0x00, 0}, {0x00, 0xaa, 0x00, 0}, {0xaa, 0x55, 0x00, 0}, {0x00, 0x00, 0xaa, 0}, {0xaa, 0x00, 0xaa, 0}, {0x00, 0xaa, 0xaa, 0}, {0xaa, 0xaa, 0xaa, 0}, {0x55, 0x55, 0x55, 0}, {0xff, 0x55, 0x55, 0}, {0x55, 0xff, 0x55, 0}, {0xff, 0xff, 0x55, 0}, {0x55, 0x55, 0xff, 0}, {0xff, 0x55, 0xff, 0}, {0x55, 0xff, 0xff, 0}, {0xff, 0xff, 0xff, 0},*/ {0x00, 0x00, 0x00, 0}, {0x80, 0x00, 0x00, 0}, {0x00, 0x80, 0x00, 0}, {0xaa, 0x55, 0x00, 0}, {0x00, 0x00, 0x80, 0}, {0x80, 0x00, 0x80, 0}, {0x00, 0x80, 0x80, 0}, {0xaa, 0xaa, 0xaa, 0}, {0x55, 0x55, 0x55, 0}, {0xff, 0x55, 0x55, 0}, {0x55, 0xff, 0x55, 0}, {0xff, 0xff, 0x55, 0}, {0x55, 0x55, 0xff, 0}, {0xff, 0x55, 0xff, 0}, {0x55, 0xff, 0xff, 0}, {0xff, 0xff, 0xff, 0}, {-1, -1, -1, 0},};/*struct rgb rgbcache = {0, 0, 0};int rgbcache_c = 0;static inline int find_nearest_color(struct rgb *r, int l){ int dist, dst, min, i; if (r->r == rgbcache.r && r->g == rgbcache.g && r->b == rgbcache.b) return rgbcache_c; dist = 0xffffff; min = 0; for (i = 0; i < l; i++) if ((dst = color_distance(r, &palette[i])) < dist) dist = dst, min = i; return min;}*/struct rgb_cache_entry { int color; int l; struct rgb rgb;};#define RGB_HASH_SIZE 4096#define HASH_RGB(r, l) ((((r)->r << 3) + ((r)->g << 2) + (r)->b + (l)) & (RGB_HASH_SIZE - 1))static inline int find_nearest_color(struct rgb *r, int l){ int dist, dst, min, i; static struct rgb_cache_entry rgb_cache[RGB_HASH_SIZE]; static int cache_init = 0; int h; if (!cache_init) goto initialize; back: h = HASH_RGB(r, l); if (rgb_cache[h].color != -1 && rgb_cache[h].l == l && rgb_cache[h].rgb.r == r->r && rgb_cache[h].rgb.g == r->g && rgb_cache[h].rgb.b == r->b) return rgb_cache[h].color; dist = 0xffffff; min = 0; for (i = 0; i < l; i++) if ((dst = color_distance(r, &palette[i])) < dist) dist = dst, min = i; rgb_cache[h].color = min; rgb_cache[h].l = l; rgb_cache[h].rgb.r = r->r; rgb_cache[h].rgb.g = r->g; rgb_cache[h].rgb.b = r->b; return min; initialize: for (h = 0; h < RGB_HASH_SIZE; h++) rgb_cache[h].color = -1; cache_init = 1; goto back;}static inline int fg_color(int fg, int bg){ int l = bg < fg ? bg : fg; int h = bg < fg ? fg : bg; if (l == h || (!l && (h == 4 || h == 8 || h == 12)) || (l == 1 && (h == 3 || h == 5 || h == 8 || h == 12)) || (l == 2 && h == 6) || (l == 3 && (h == 5 || h == 12)) || (l == 4 && (h == 8 || h == 12)) || (l == 5 && (h == 8 || h == 12))) return (fg == 4 || fg == 12) && (bg == 0 || bg == 8) ? 6 : (7 - 7 * (bg == 2 || bg == 6 || bg == 7)); return fg;}#define XALIGN(x) (((x)+0x7f)&~0x7f)int nowrap = 0;static inline void xpand_lines(struct part *p, int y){ /*if (y >= p->y) p->y = y + 1;*/ if (!p->data) return; if (XALIGN((unsigned)y + (unsigned)p->yp) > MAXINT) overalloc(); y += p->yp; if (y >= p->data->y) { /* !!! FIXME: out of inline */ int i; if (XALIGN(y + 1) > XALIGN(p->data->y)) { if (XALIGN((unsigned)y + 1) > MAXINT / sizeof(struct line)) overalloc(); p->data->data = mem_realloc(p->data->data, XALIGN(y+1)*sizeof(struct line)); } for (i = p->data->y; i <= y; i++) { p->data->data[i].l = 0; p->data->data[i].c = p->bgcolor; p->data->data[i].d = DUMMY; } p->data->y = i; }}static inline void xpand_line(struct part *p, int y, int x){ if (!p->data) return; /* !!! FIXME: p->x (?) */ if (XALIGN((unsigned)x + (unsigned)p->xp) > MAXINT) overalloc(); x += p->xp; y += p->yp;#ifdef DEBUG if (y >= p->data->y) { internal("line does not exist"); return; }#endif if (x >= p->data->data[y].l) { /* !!! FIXME: out of inline */ int i; if (XALIGN(x+1) > XALIGN(p->data->data[y].l)) { if (XALIGN((unsigned)x + 1) > MAXINT / sizeof(chr)) overalloc(); p->data->data[y].d = mem_realloc(p->data->data[y].d, XALIGN(x+1)*sizeof(chr)); } for (i = p->data->data[y].l; i <= x; i++) p->data->data[y].d[i] = (p->data->data[y].c << 11) | ' '; p->data->data[y].c = p->bgcolor; p->data->data[y].l = i; }}void r_xpand_spaces(struct part *p, int l){ unsigned char *c; if ((unsigned)l >= MAXINT) overalloc(); c = mem_realloc(p->spaces, l + 1); memset(c + p->spl, 0, l - p->spl + 1); p->spl = l + 1; p->spaces = c;}static inline void xpand_spaces(struct part *p, int l){ if ((unsigned)l >= (unsigned)p->spl) r_xpand_spaces(p, l);}#define POS(x, y) (p->data->data[p->yp + (y)].d[p->xp + (x)])#define LEN(y) (p->data->data[p->yp + (y)].l - p->xp < 0 ? 0 : p->data->data[p->yp + (y)].l - p->xp)#define SLEN(y, x) p->data->data[p->yp + (y)].l = p->xp + x;#define X(x) (p->xp + (x))#define Y(y) (p->yp + (y))static inline void set_hchar(struct part *p, int x, int y, unsigned c){ xpand_lines(p, y); xpand_line(p, y, x); POS(x, y) = c;}static inline void set_hchars(struct part *p, int x, int y, int xl, unsigned c){ xpand_lines(p, y); xpand_line(p, y, x+xl-1); for (; xl; xl--, x++) POS(x, y) = c;}void xset_hchar(struct part *p, int x, int y, unsigned c){ set_hchar(p, x, y, c);}void xset_hchars(struct part *p, int x, int y, int xl, unsigned c){ set_hchars(p, x, y, xl, c);}void xxpand_lines(struct part *p, int y){ xpand_lines(p, y);}void xxpand_line(struct part *p, int y, int x){ xpand_line(p, y, x);}static inline void set_hline(struct part *p, int x, int y, int xl, unsigned char *d, unsigned c, int spc){ xpand_lines(p, y); xpand_line(p, y, x+xl-1); if (spc) xpand_spaces(p, x+xl-1); for (; xl; xl--, x++, d++) { if (spc) p->spaces[x] = *d == ' '; if (p->data) POS(x, y) = *d | c; }}int last_link_to_move;struct tag *last_tag_to_move;struct tag *last_tag_for_newline;static inline void move_links(struct part *p, int xf, int yf, int xt, int yt){ int n; struct tag *t; int w = 0; if (!p->data) return; xpand_lines(p, yt); for (n = last_link_to_move; n < p->data->nlinks; n++) { int i; struct link *link = &p->data->links[n]; /*printf("ml: %d %d %d %d",link->pos[0].x,link->pos[0].y,X(xf),Y(yf));fflush(stdout);sleep(1);*/ /*for (i = 0; i < link->n; i++) fprintf(stderr, "%d.%d -> %d.%d: %d.%d : %d %d\n", X(xf), Y(yf), X(xt), yt != -1 ? Y(yt) : -1, n, i, link->pos[i].x, link->pos[i].y);*/ for (i = 0; i < link->n; i++) if (link->pos[i].y >= Y(yf)) { w = 1; if (link->pos[i].y == Y(yf) && link->pos[i].x >= X(xf)) { if (yt >= 0) link->pos[i].y = Y(yt), link->pos[i].x += -xf + xt; else memmove(&link->pos[i], &link->pos[i+1], (link->n-i-1) * sizeof(struct point)), link->n--, i--; } } /*if (!link->n) { if (link->where) mem_free(link->where); if (link->target) mem_free(link->target); if (link->where_img) mem_free(link->where_img); if (link->pos) mem_free(link->pos); memmove(link, link + 1, (p->data->nlinks - n - 1) * sizeof(struct link)); p->data->nlinks --; n--; }*/ if (!w /*&& n >= 0*/) last_link_to_move = n; } w = 0; if (yt >= 0) for (t = last_tag_to_move->next; (void *)t != &p->data->tags; t = t->next) { if (t->y == Y(yf)) { w = 1; if (t->x >= X(xf)) { t->y = Y(yt), t->x += -xf + xt; } } if (!w) last_tag_to_move = t; }}static inline void copy_chars(struct part *p, int x, int y, int xl, chr *d){ if (xl <= 0) return; xpand_lines(p, y); xpand_line(p, y, x+xl-1); for (; xl; xl--, x++, d++) POS(x, y) = *d;}static inline void move_chars(struct part *p, int x, int y, int nx, int ny){ if (LEN(y) - x <= 0) return; copy_chars(p, nx, ny, LEN(y) - x, &POS(x, y)); SLEN(y, x); move_links(p, x, y, nx, ny);}static inline void shift_chars(struct part *p, int y, int s){ chr *a; int l = LEN(y); if ((unsigned)l > MAXINT / sizeof(chr)) overalloc(); a = mem_alloc(l * sizeof(chr)); memcpy(a, &POS(0, y), l * sizeof(chr)); set_hchars(p, 0, y, s, (p->data->data[y].c << 11) | ' '); copy_chars(p, s, y, l, a); mem_free(a); move_links(p, 0, y, s, y);}static inline void del_chars(struct part *p, int x, int y){ SLEN(y, x); move_links(p, x, y, -1, -1);}#define rm(x) ((x).width - (x).rightmargin > 0 ? (x).width - (x).rightmargin : 0)void line_break(struct part *);int split_line(struct part *p){ int i; /*if (!p->data) goto r;*/ /*printf("split: %d,%d , %d,%d,%d\n",p->cx,p->cy,par_format.rightmargin,par_format.leftmargin,p->cx);*/ for (i = rm(par_format); i >= par_format.leftmargin; i--) if (i < p->spl && p->spaces[i]) goto split; /*for (i = p->cx - 1; i > rm(par_format) && i > par_format.leftmargin; i--)*/ for (i = par_format.leftmargin; i < p->cx ; i++) if (i < p->spl && p->spaces[i]) goto split; /*for (i = rm(par_format); i >= par_format.leftmargin; i--) if ((POS(i, p->cy) & 0xff) == ' ') goto split; for (i = p->cx - 1; i > rm(par_format) && i > par_format.leftmargin; i--) if ((POS(i, p->cy) & 0xff) == ' ') goto split;*/ if (p->cx + par_format.rightmargin > p->x) p->x = p->cx + par_format.rightmargin; /*if (p->y < p->cy + 1) p->y = p->cy + 1; p->cy++; p->cx = -1; memset(p->spaces, 0, p->spl); if (p->data) xpand_lines(p, p->cy + 1);*/ /*line_break(p);*/ return 0; split: if (i + par_format.rightmargin > p->x) p->x = i + par_format.rightmargin; if (p->data) {#ifdef DEBUG if ((POS(i, p->cy) & 0xff) != ' ') internal("bad split: %c", (char)POS(i, p->cy));#endif move_chars(p, i+1, p->cy, par_format.leftmargin, p->cy+1); del_chars(p, i, p->cy); } memmove(p->spaces, p->spaces + i + 1, p->spl - i - 1); memset(p->spaces + p->spl - i - 1, 0, i + 1); memmove(p->spaces + par_format.leftmargin, p->spaces, p->spl - par_format.leftmargin); p->cy++; p->cx -= i - par_format.leftmargin + 1; /*return 1 + (p->cx == par_format.leftmargin);*/ if (p->cx == par_format.leftmargin) p->cx = -1; if (p->y < p->cy + (p->cx != -1)) p->y = p->cy + (p->cx != -1); return 1 + (p->cx == -1);}void align_line(struct part *p, int y){ int na; if (!p->data) return; if (!LEN(y) || par_format.align == AL_LEFT || par_format.align == AL_NO || par_format.align == AL_BLOCK /* !!! fixme! */) return; na = rm(par_format) - LEN(y); if (par_format.align == AL_CENTER) na /= 2; if (na > 0) shift_chars(p, y, na);}struct link *new_link(struct f_data *f){ if (!f) return NULL; if (!(f->nlinks & (ALLOC_GR - 1))) { if ((unsigned)f->nlinks > MAXINT / sizeof(struct link) - ALLOC_GR) overalloc(); f->links = mem_realloc(f->links, (f->nlinks + ALLOC_GR) * sizeof(struct link)); } memset(&f->links[f->nlinks], 0, sizeof(struct link)); return &f->links[f->nlinks++];}void html_tag(struct f_data *f, unsigned char *t, int x, int y){ struct tag *tag; unsigned char *tt; int ll; if (!f) return; tt = init_str(); ll = 0; add_conv_str(&tt, &ll, t, strlen(t), -2); tag = mem_alloc(sizeof(struct tag) + strlen(tt) + 1); tag->x = x; tag->y = y; strcpy(tag->name, tt); add_to_list(f->tags, tag); if ((void *)last_tag_for_newline == &f->tags) last_tag_for_newline = tag; mem_free(tt);}unsigned char *last_link;unsigned char *last_target;unsigned char *last_image;struct form_control *last_form;int nobreak;struct conv_table *convert_table;void put_chars(struct part *, unsigned char *, int);#define CH_BUF 256int put_chars_conv(struct part *p, unsigned char *c, int l){ static char buffer[CH_BUF]; int bp = 0; int pp = 0; int total = 0; if (format.attr & AT_GRAPHICS) { put_chars(p, c, l); return l; } if (!l) put_chars(p, NULL, 0); while (pp < l) { unsigned char *e; if (c[pp] < 128 && c[pp] != '&') { putc: buffer[bp++] = c[pp++]; if (bp < CH_BUF) continue; goto flush; } if (c[pp] != '&') { struct conv_table *t; int i; if (!convert_table) goto putc; t = convert_table; i = pp; decode: if (!t[c[i]].t) { e = t[c[i]].u.str; } else { t = t[c[i++]].u.tbl; if (i >= l) goto putc; goto decode; } pp = i + 1; } else { int i = pp + 1; if (d_opt->plain) goto putc; while (i < l && c[i] != ';' && c[i] != '&' && c[i] > ' ') i++; if (!(e = get_entity_string(&c[pp + 1], i - pp - 1, d_opt->cp))) goto putc; pp = i + (i < l && c[i] == ';'); } if (!e[0]) continue; if (!e[1]) { buffer[bp++] = e[0]; if (bp < CH_BUF) continue; flush: e = ""; goto flush1; } while (*e) { buffer[bp++] = *(e++); if (bp < CH_BUF) continue; flush1: put_chars(p, buffer, bp); total += bp; bp = 0; } } if (bp) put_chars(p, buffer, bp); total += bp; return total;}void put_chars(struct part *p, unsigned char *c, int l){ static struct text_attrib_beginning ta_cache = { -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -