📄 html_r.c
字号:
/* html_r.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"#define format format_struct f_data *init_formatted(struct document_options *opt){ struct f_data *scr; scr = mem_calloc(sizeof(struct f_data)); copy_opt(&scr->opt, opt); scr->data = DUMMY; scr->nlinks = 0; scr->links = DUMMY; scr->nlink_events = 0; scr->link_events = DUMMY; init_list(scr->forms); init_list(scr->tags); init_list(scr->nodes);#ifdef G scr->n_images=0; init_list(scr->images); scr->search_positions = DUMMY; scr->search_lengths = DUMMY; init_list(scr->image_refresh); scr->start_highlight_x = -1; scr->start_highlight_y = -1; scr->hlt_pos = -1;#endif return scr;}/* prototypes */void clear_formatted(struct f_data *);void r_xpand_spaces(struct part *, int);int split_line(struct part *);int put_chars_conv(struct part *, unsigned char *, int);void html_form_control(struct part *, struct form_control *);void add_frameset_entry(struct frameset_desc *, struct frameset_desc *, unsigned char *, unsigned char *, int, int, unsigned char);void *html_special(struct part *, int, ...);void do_format(char *, char *, struct part *, unsigned char *);void release_part(struct part *);void push_base_format(unsigned char *, struct document_options *, int);void add_srch_chr(struct f_data *, unsigned char, int, int, int);void sort_srch(struct f_data *);int get_srch(struct f_data *);void destroy_fc(struct form_control *fc){ int i; if (fc->action) mem_free(fc->action); if (fc->target) mem_free(fc->target); if (fc->form_name) mem_free(fc->form_name); if (fc->onsubmit) mem_free(fc->onsubmit); if (fc->name) mem_free(fc->name); if (fc->alt) mem_free(fc->alt); if (fc->default_value) mem_free(fc->default_value); for (i = 0; i < fc->nvalues; i++) { if (fc->values[i]) mem_free(fc->values[i]); if (fc->labels[i]) mem_free(fc->labels[i]); } if (fc->values) mem_free(fc->values); if (fc->labels) mem_free(fc->labels); if (fc->menu) free_menu(fc->menu);}void free_frameset_desc(struct frameset_desc *fd){ int i; for (i = 0; i < fd->n; i++) { if (fd->f[i].subframe) free_frameset_desc(fd->f[i].subframe); if (fd->f[i].name) mem_free(fd->f[i].name); if (fd->f[i].url) mem_free(fd->f[i].url); }#ifdef JS if (fd->onload_code)mem_free(fd->onload_code);#endif mem_free(fd);}struct frameset_desc *copy_frameset_desc(struct frameset_desc *fd){ int i; struct frameset_desc *new; if ((unsigned)fd->n > MAXINT / sizeof(struct frame_desc)) overalloc(); new = mem_alloc(sizeof(struct frameset_desc) + fd->n * sizeof(struct frame_desc)); memcpy(new, fd, sizeof(struct frameset_desc) + fd->n * sizeof(struct frame_desc));#ifdef JS if (new->onload_code) new->onload_code = stracpy(new->onload_code);#endif for (i = 0; i < new->n; i++) { if (new->f[i].subframe) new->f[i].subframe = copy_frameset_desc(new->f[i].subframe); if (new->f[i].name) new->f[i].name = stracpy(new->f[i].name); if (new->f[i].url) new->f[i].url = stracpy(new->f[i].url); } return new;}void free_additional_files(struct additional_files **a){ struct additional_file *af; if (!*a) return; if (--(*a)->refcount) { *a = NULL; return; } foreach(af, (*a)->af) release_object(&af->rq); free_list((*a)->af); mem_free(*a); *a = NULL;}void clear_formatted(struct f_data *scr){ int n; int y; struct form_control *fc; if (!scr) return;#ifdef G if (scr->root) scr->root->destruct(scr->root);#endif release_object(&scr->rq); free_additional_files(&scr->af); if (scr->title) mem_free(scr->title); if (/*!scr->frame_desc_link &&*/ scr->frame_desc) { free_frameset_desc(scr->frame_desc); } for (n = 0; n < scr->nlinks; n++) { struct link *l = &scr->links[n]; if (l->where) mem_free(l->where); if (l->target) mem_free(l->target); if (l->where_img) mem_free(l->where_img); if (l->img_alt) mem_free(l->img_alt); if (l->pos) mem_free(l->pos); free_js_event_spec(l->js_event); } mem_free(scr->links); for (n = 0; n < scr->nlink_events; n++) { free_js_event_spec(scr->link_events[n]); } mem_free(scr->link_events); if (!F) for (y = 0; y < scr->y; y++) mem_free(scr->data[y].d); mem_free(scr->data); if (scr->lines1) mem_free(scr->lines1); if (scr->lines2) mem_free(scr->lines2); if (scr->opt.framename) mem_free(scr->opt.framename); foreach(fc, scr->forms) { destroy_fc(fc); } free_list(scr->forms); free_list(scr->tags); free_list(scr->nodes); if (scr->search) mem_free(scr->search); if (scr->slines1) mem_free(scr->slines1); if (scr->slines2) mem_free(scr->slines2);#ifdef G free_list(scr->image_refresh); if (scr->srch_string) mem_free(scr->srch_string); if (scr->last_search) mem_free(scr->last_search); if (scr->search_positions) mem_free(scr->search_positions); if (scr->search_lengths) mem_free(scr->search_lengths);#endif if (scr->refresh) mem_free(scr->refresh); jsint_destroy_document_description(scr); if (scr->script_href_base) mem_free(scr->script_href_base); free_js_event_spec(scr->js_event);}void destroy_formatted(struct f_data *scr){ if (scr->fd) { internal("trying to free locked formatted data"); return; } clear_formatted(scr); /*del_from_list(scr);*/ mem_free(scr);}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) { 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; 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) { 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->img_alt) mem_free(link->img_alt); 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){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -