📄 html_tbl.c
字号:
/* html_tbl.c * Tables in HTML * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"#define format format_#ifdef DEBUG#undef DEBUG#endif/*#define DEBUG*/#define RECT_BOUND_BITS 10 /* --- bound at 1024 pixels */#define AL_TR -1#define VAL_TR -1#define VAL_TOP 0#define VAL_MIDDLE 1#define VAL_BOTTOM 2#define W_AUTO -1#define W_REL -2#define F_VOID 0#define F_ABOVE 1#define F_BELOW 2#define F_HSIDES 3#define F_LHS 4#define F_RHS 8#define F_VSIDES 12#define F_BOX 15#define R_NONE 0#define R_ROWS 1#define R_COLS 2#define R_ALL 3#define R_GROUPS 4void get_align(char *, int *);void get_valign(char *, int *);void get_c_width(char *, int *, int);void get_align(char *attr, int *a){ char *al; if ((al = get_attr_val(attr, "align"))) { if (!(strcasecmp(al, "left"))) *a = AL_LEFT; if (!(strcasecmp(al, "right"))) *a = AL_RIGHT; if (!(strcasecmp(al, "center"))) *a = AL_CENTER; if (!(strcasecmp(al, "justify"))) *a = AL_BLOCK; if (!(strcasecmp(al, "char"))) *a = AL_RIGHT; /* NOT IMPLEMENTED */ mem_free(al); }}void get_valign(char *attr, int *a){ char *al; if ((al = get_attr_val(attr, "valign"))) { if (!(strcasecmp(al, "top"))) *a = VAL_TOP; if (!(strcasecmp(al, "middle"))) *a = VAL_MIDDLE; if (!(strcasecmp(al, "bottom"))) *a = VAL_BOTTOM; if (!(strcasecmp(al, "baseline"))) *a = VAL_TOP; /* NOT IMPLEMENTED */ mem_free(al); }}void get_c_width(char *attr, int *w, int sh){ char *al; if ((al = get_attr_val(attr, "width"))) { if (*al && al[strlen(al) - 1] == '*') { char *en; unsigned long n; al[strlen(al) - 1] = 0; n = strtoul(al, &en, 10); if (n < 10000 && !*en) *w = W_REL - n; } else { int p = get_width(attr, "width", sh); if (p >= 0) *w = p; } mem_free(al); }}#define INIT_X 8#define INIT_Y 8struct table_cell { int used; int spanned; int mx, my; unsigned char *start; unsigned char *end; int align; int valign; int b; struct rgb bgcolor; int group; int colspan; int rowspan; int min_width; int max_width; int x_width; int height; int xpos, ypos, xw, yw; int link_num;#ifdef G unsigned char bgcolor_str[8]; struct g_object_area *root; struct rect_set *brd; int g_width; struct rect rect; int dgen;#endif};struct table_column { int group; int align; int valign; int width;};struct table { struct part *p;#ifdef G struct g_part *gp;#endif int x, y; int rx, ry; int align; int border, cellpd, vcellpd, cellsp; int frame, rules, width, wf; unsigned char *bordercolor; int *min_c, *max_c; int *w_c; int rw; int min_t, max_t; struct table_cell *cells; int c, rc; struct table_column *cols; int xc; int *xcols; int *r_heights; int rh; int link_num; struct rgb bgcolor;#ifdef G struct background *bg; struct background *frame_bg; struct rect_set **r_bg; int nr_bg; struct rect_set **r_frame; int nr_frame; struct table_cell ***r_cells; int *w_cells; int nr_cells;#endif};/* prototype */void free_table(struct table *);void expand_cells(struct table *, int, int);struct table_cell *new_cell(struct table *, int, int);void new_columns(struct table *, int, int, int, int, int);void set_td_width(struct table *, int, int, int);void get_cell_widths(struct table *);void dst_width(int *, int, int, int *);int get_vline_width(struct table *, int);int get_hline_width(struct table *, int);int g_get_vline_pad(struct table *, int, int *, int *);int g_get_hline_pad(struct table *, int, int *, int *);int get_column_widths(struct table *);void get_table_width(struct table *);void distribute_widths(struct table *, int);void check_table_widths(struct table *);void get_table_heights(struct table *);void display_complicated_table(struct table *, int, int, int *);void get_table_frame(struct table *, signed char *, signed char *);void display_table_frames(struct table *, int, int);#ifdef Gvoid add_to_rect_sets(struct rect_set ***, int *, struct rect *);void add_to_cell_sets(struct table_cell ****, int **, int *, struct rect *, struct table_cell *);void table_mouse_event(struct f_data_c *, struct g_object_table *, int, int, int);void draw_rect_set(struct graphics_device *, struct background *, struct rect_set *, int, int);void draw_rect_sets(struct graphics_device *, struct background *, struct rect_set **, int, int, int);void table_draw(struct f_data_c *, struct g_object_table *, int, int);void table_destruct(struct g_object_table *);void table_get_list(struct g_object_table *, void (*)(struct g_object *, struct g_object *));#endifstruct table *new_table(void);void get_cell_width(char *, char *, int, int, int, int *, int *, int, int *, unsigned char *);#ifdef DEBUG#define CELL(t, x, y) (((x) < 0 || (x) >= (t)->rx || (y) < 0 || (y) >= (t)->ry) ? (internal("accessing cell out of table (%d,%d) - limit (%d,%d)", (x), (y), (t)->rx, (t)->ry), (t)->cells) : &(t)->cells[(y) * (t)->rx + (x)])#else#define CELL(t, x, y) (&(t)->cells[(y) * (t)->rx + (x)])#endifunsigned char frame_table[81] = { 0x00, 0xb3, 0xba, 0xc4, 0xc0, 0xd3, 0xcd, 0xd4, 0xc8, 0xc4, 0xd9, 0xbd, 0xc4, 0xc1, 0xd0, 0xcd, 0xd4, 0xc8, 0xcd, 0xbe, 0xbc, 0xcd, 0xbe, 0xbc, 0xcd, 0xcf, 0xca, 0xb3, 0xb3, 0xba, 0xda, 0xc3, 0xd3, 0xd5, 0xc6, 0xc8, 0xbf, 0xb4, 0xbd, 0xc2, 0xc5, 0xd0, 0xd5, 0xc6, 0xc8, 0xb8, 0xb5, 0xbc, 0xb8, 0xb5, 0xbc, 0xd1, 0xd8, 0xca, 0xba, 0xba, 0xba, 0xd6, 0xd6, 0xc7, 0xc9, 0xc9, 0xcc, 0xb7, 0xb7, 0xb6, 0xd2, 0xd2, 0xd7, 0xc9, 0xc9, 0xcc, 0xbb, 0xbb, 0xb9, 0xbb, 0xbb, 0xb9, 0xcb, 0xcb, 0xce,};unsigned char hline_table[3] = { 0x20, 0xc4, 0xcd };unsigned char vline_table[3] = { 0x20, 0xb3, 0xba };struct table *new_table(void){ struct table *t; t = mem_calloc(sizeof(struct table)); t->p = NULL;#ifdef G t->gp = NULL; t->r_frame = DUMMY; t->nr_frame = 0; t->r_bg = DUMMY; t->nr_bg = 0; t->r_cells = DUMMY; t->w_cells = DUMMY; t->nr_cells = 0;#endif t->x = t->y = 0; t->rx = INIT_X; t->ry = INIT_Y; t->cells = mem_calloc(INIT_X * INIT_Y * sizeof(struct table_cell)); t->c = 0; t->rc = INIT_X; t->cols = mem_calloc(INIT_X * sizeof(struct table_column)); t->xcols = DUMMY; t->xc = 0; t->r_heights = DUMMY; return t;}void free_table(struct table *t){#ifdef G if (F) { int i, j; for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) { struct table_cell *c = CELL(t, i, j); if (c->root) c->root->destruct(c->root); if (c->brd) mem_free(c->brd); } for (i = 0; i < t->nr_frame; i++) mem_free(t->r_frame[i]); if (t->r_frame) mem_free(t->r_frame); for (i = 0; i < t->nr_bg; i++) mem_free(t->r_bg[i]); if (t->r_bg) mem_free(t->r_bg); for (i = 0; i < t->nr_cells; i++) mem_free(t->r_cells[i]); mem_free(t->r_cells), mem_free(t->w_cells); if (t->frame_bg) g_release_background(t->frame_bg); }#endif if (t->bordercolor) mem_free(t->bordercolor); if (t->min_c) mem_free(t->min_c); if (t->max_c) mem_free(t->max_c); if (t->w_c) mem_free(t->w_c); mem_free(t->r_heights); mem_free(t->cols); mem_free(t->xcols); mem_free(t->cells); mem_free(t);}void expand_cells(struct table *t, int x, int y){ int i, j; if (x >= t->x) { if (t->x) { for (i = 0; i < t->y; i++) if (CELL(t, t->x - 1, i)->colspan == -1) { for (j = t->x; j <= x; j++) { CELL(t, j, i)->used = 1; CELL(t, j, i)->spanned = 1; CELL(t, j, i)->rowspan = CELL(t, t->x - 1, i)->rowspan; CELL(t, j, i)->colspan = -1; CELL(t, j, i)->mx = CELL(t, t->x - 1, i)->mx; CELL(t, j, i)->my = CELL(t, t->x - 1, i)->my; } } } t->x = x + 1; } if (y >= t->y) { if (t->y) { for (i = 0; i < t->x; i++) if (CELL(t, i, t->y - 1)->rowspan == -1) { for (j = t->y; j <= y; j++) { CELL(t, i, j)->used = 1; CELL(t, i, j)->spanned = 1; CELL(t, i, j)->rowspan = -1; CELL(t, i, j)->colspan = CELL(t, i, t->y - 1)->colspan; CELL(t, i, j)->mx = CELL(t, i, t->y - 1)->mx; CELL(t, i, j)->my = CELL(t, i, t->y - 1)->my; } } } t->y = y + 1; }}struct table_cell *new_cell(struct table *t, int x, int y){ struct table nt; int i, j; if (x < t->x && y < t->y) goto ret; rep: if (x < t->rx && y < t->ry) { expand_cells(t, x, y); goto ret; } nt.rx = t->rx; nt.ry = t->ry; while (x >= nt.rx) { if ((unsigned)nt.rx > MAXINT / 2) overalloc(); nt.rx *= 2; } while (y >= nt.ry) { if ((unsigned)nt.ry > MAXINT / 2) overalloc(); nt.ry *= 2; } if ((unsigned)nt.rx * (unsigned)nt.ry / (unsigned)nt.rx != (unsigned)nt.ry) overalloc(); if ((unsigned)nt.rx * (unsigned)nt.ry > MAXINT / sizeof(struct table_cell)) overalloc(); nt.cells = mem_calloc(nt.rx * nt.ry * sizeof(struct table_cell)); for (i = 0; i < t->x; i++) for (j = 0; j < t->y; j++) memcpy(CELL(&nt, i, j), CELL(t, i, j), sizeof(struct table_cell)); mem_free(t->cells); t->cells = nt.cells; t->rx = nt.rx; t->ry = nt.ry; goto rep; ret: return CELL(t, x, y);}void new_columns(struct table *t, int span, int width, int align, int valign, int group){ if ((unsigned)t->c + (unsigned)span > MAXINT) overalloc(); if (t->c + span > t->rc) { int n = t->rc; struct table_column *nc; while (t->c + span > n) { if ((unsigned)n > MAXINT / 2) overalloc(); n *= 2; } if ((unsigned)n > MAXINT / sizeof(struct table_column)) overalloc(); nc = mem_realloc(t->cols, n * sizeof(struct table_column)); t->rc = n; t->cols = nc; } while (span--) { t->cols[t->c].align = align; t->cols[t->c].valign = valign; t->cols[t->c].width = width; t->cols[t->c++].group = group; group = 0; }}void set_td_width(struct table *t, int x, int width, int f){ if (x >= t->xc) { int n = t->xc ? t->xc : 1; int i; int *nc; while (x >= n) { if ((unsigned)n > MAXINT / 2) overalloc(); n *= 2; } if ((unsigned)n > MAXINT / sizeof(int)) overalloc(); nc = mem_realloc(t->xcols, n * sizeof(int)); for (i = t->xc; i < n; i++) nc[i] = W_AUTO; t->xc = n; t->xcols = nc; } if (t->xcols[x] == W_AUTO || f) { set: t->xcols[x] = width; return; } if (width == W_AUTO) return; if (width < 0 && t->xcols[x] >= 0) goto set; if (width >= 0 && t->xcols[x] < 0) return; t->xcols[x] = (t->xcols[x] + width) / 2;}unsigned char *skip_element(unsigned char *html, unsigned char *eof, unsigned char *what, int sub){ int l = strlen(what); int level = 1; unsigned char *name; int namelen; r: while (html < eof && (*html != '<')) rr:html++; if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) { html = skip_comment(html, eof); goto r; } if (html >= eof) return eof; if (parse_element(html, eof, &name, &namelen, NULL, &html)) goto rr; if (namelen == l && !casecmp(name, what, l) && sub) level++; if (namelen == l + 1 && name[0] == '/' && !casecmp(name + 1, what, l)) if (!--level) return html; goto r;}struct s_e { unsigned char *s, *e;};struct table *parse_table(unsigned char *, unsigned char *, unsigned char **, struct rgb *, int, struct s_e **, int *); /* prototype */struct table *parse_table(unsigned char *html, unsigned char *eof, unsigned char **end, struct rgb *bgcolor, int sh, struct s_e **bad_html, int *bhp){ int qqq; struct table *t; struct table_cell *cell; unsigned char *t_name, *t_attr, *en; int t_namelen; int x = 0, y = -1; int p = 0; unsigned char *lbhp = NULL; int l_al = AL_LEFT; int l_val = VAL_MIDDLE; int csp, rsp; int group = 0; int i, j, k; struct rgb l_col; int c_al = AL_TR, c_val = VAL_TR, c_width = W_AUTO, c_span = 0; memcpy(&l_col, bgcolor, sizeof(struct rgb)); *end = html; if (bad_html) { *bad_html = DUMMY; *bhp = 0; } if (!(t = new_table())) return NULL; memcpy(&t->bgcolor, bgcolor, sizeof(struct rgb)); se: en = html; see: html = en; if (bad_html && !p && !lbhp) { if (!(*bhp & (ALLOC_GR-1))) { if ((unsigned)*bhp > MAXINT / sizeof(struct s_e) - ALLOC_GR) overalloc();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -