📄 html_tbl.c
字号:
if (!F && border > 2) border = 2; if (!F && cellsp > 2) cellsp = 2; if (F && !cellsp && border) cellsp = 1; align = par_format.align; if (align == AL_NO || align == AL_BLOCK) align = AL_LEFT; if ((al = get_attr_val(attr, "align"))) { if (!strcasecmp(al, "left")) align = AL_LEFT; if (!strcasecmp(al, "center")) align = AL_CENTER; if (!strcasecmp(al, "right")) align = AL_RIGHT; mem_free(al); } frame = F_BOX; if ((al = get_attr_val(attr, "frame"))) { if (!strcasecmp(al, "void")) frame = F_VOID; if (!strcasecmp(al, "above")) frame = F_ABOVE; if (!strcasecmp(al, "below")) frame = F_BELOW; if (!strcasecmp(al, "hsides")) frame = F_HSIDES; if (!strcasecmp(al, "vsides")) frame = F_VSIDES; if (!strcasecmp(al, "lhs")) frame = F_LHS; if (!strcasecmp(al, "rhs")) frame = F_RHS; if (!strcasecmp(al, "box")) frame = F_BOX; if (!strcasecmp(al, "border")) frame = F_BOX; mem_free(al); } rules = border ? R_ALL : R_NONE; if ((al = get_attr_val(attr, "rules"))) { if (!strcasecmp(al, "none")) rules = R_NONE; if (!strcasecmp(al, "groups")) rules = R_GROUPS; if (!strcasecmp(al, "rows")) rules = R_ROWS; if (!strcasecmp(al, "cols")) rules = R_COLS; if (!strcasecmp(al, "all")) rules = R_ALL; mem_free(al); } if (!border) frame = F_VOID; wf = 0; if ((width = get_width(attr, "width", gf_val(p->data || p->xp, !!gp->data))) == -1) { width = par_format.width - (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN); if (width < 0) width = 0; wf = 1; } if (!(t = parse_table(html, eof, end, &bgcolor, gf_val(p->data || p->xp, !!gp->data), &bad_html, &bad_html_n))) { if (bad_html) mem_free(bad_html); goto ret0; } for (i = 0; i < bad_html_n; i++) { while (bad_html[i].s < bad_html[i].e && WHITECHAR(*bad_html[i].s)) bad_html[i].s++; while (bad_html[i].s < bad_html[i].e && WHITECHAR(bad_html[i].e[-1])) bad_html[i].e--; if (bad_html[i].s < bad_html[i].e) parse_html(bad_html[i].s, bad_html[i].e, put_chars_f, line_break_f, special_f, gf_val((void *)p, (void *)gp), NULL); } mem_free(bad_html); html_stack_dup(); html_top.dontkill = 1; par_format.align = AL_LEFT;#ifdef G if (F) { t->gp = gp; } else#endif { t->p = p; } t->bordercolor = get_attr_val(attr, "bordercolor"); t->align = align; t->border = border; t->cellpd = cellpd; t->vcellpd = vcellpd; t->cellsp = cellsp; t->frame = frame; t->rules = rules; t->width = width; t->wf = wf; cpd_pass = 0; cpd_last = t->cellpd; cpd_width = 0; /* not needed, but let the warning go away */ again: get_cell_widths(t); if (get_column_widths(t)) goto ret2; get_table_width(t); if (gf_val(!p->data && !p->xp, !gp->data)) { if (!wf && t->max_t > width) t->max_t = width; if (t->max_t < t->min_t) t->max_t = t->min_t; if (t->max_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN) > gf_val(p->xmax, gp->xmax)) *gf_val(&p->xmax, &gp->xmax) = t->max_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN); if (t->min_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN) > gf_val(p->x, gp->x)) *gf_val(&p->x, &gp->x) = t->min_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN); goto ret2; } if (!F && !cpd_pass && t->min_t > width && t->cellpd) { t->cellpd = 0; cpd_pass = 1; cpd_width = t->min_t; goto again; } if (cpd_pass == 1 && t->min_t > cpd_width) { t->cellpd = cpd_last; cpd_pass = 2; goto again; } /*debug("%d %d %d", t->min_t, t->max_t, width);*/ if (t->min_t >= width) distribute_widths(t, t->min_t); else if (t->max_t < width && wf) distribute_widths(t, t->max_t); else distribute_widths(t, width); if (!F && !p->data && p->xp == 1) { int ww = t->rw + par_format.leftmargin + par_format.rightmargin; if (ww > par_format.width) ww = par_format.width; if (ww < t->rw) ww = t->rw; if (ww > p->x) p->x = ww; p->cy += t->rh; goto ret2; }#ifdef HTML_TABLE_2ND_PASS if (!F) check_table_widths(t);#endif get_table_heights(t);#ifdef G if (F) { gp->link_num = t->link_num; process_g_table(gp, t); t = NULL; goto ret3; }#endif x = par_format.leftmargin; if (align == AL_CENTER) x = (par_format.width + par_format.leftmargin - par_format.rightmargin - t->rw) / 2; if (align == AL_RIGHT) x = par_format.width - par_format.rightmargin - t->rw; if (x + t->rw > par_format.width) x = par_format.width - t->rw; if (x < 0) x = 0; /*display_table(t, x, p->cy, &cye);*/ if (!p->data) { if (t->rw + par_format.leftmargin + par_format.rightmargin > p->x) p->x = t->rw + par_format.leftmargin + par_format.rightmargin; p->cy += t->rh; goto ret2; } n = p->data->nodes.next; n->yw = p->yp - n->y + p->cy; display_complicated_table(t, x, p->cy, &cye); display_table_frames(t, x, p->cy); nn = mem_alloc(sizeof(struct node)); nn->x = n->x; nn->y = p->yp + cye; nn->xw = n->xw; add_to_list(p->data->nodes, nn); /*if (p->cy + t->rh != cye) internal("size does not match; 1:%d, 2:%d", p->cy + t->rh, cye);*/ p->cy = cye; ret2: *gf_val(&p->link_num, &gp->link_num) = t->link_num;#ifdef G ret3:#endif if (!F) if (p->cy > p->y) p->y = p->cy; if (t) free_table(t); kill_html_stack_item(&html_top); ret0: table_level--; if (!table_level) { if (!F) free_table_cache();#ifdef G else g_free_table_cache();#endif }}#ifdef Gvoid add_to_rect_sets(struct rect_set ***s, int *n, struct rect *r){ int i, j; for (i = r->y1 >> RECT_BOUND_BITS; i <= (r->y2 - 1) >> RECT_BOUND_BITS; i++) { if (i >= *n) { struct rect_set **ns; if ((unsigned)i > MAXINT / sizeof(struct rect_set *) - 1) overalloc(); ns = mem_realloc(*s, (i + 1) * sizeof(struct rect_set *)); for (j = *n; j < i + 1; j++) ns[j] = init_rect_set(); *s = ns; *n = i + 1; } add_to_rect_set(&(*s)[i], r); }}void add_to_cell_sets(struct table_cell ****s, int **nn, int *n, struct rect *r, struct table_cell *c){ int i, j; for (i = r->y1 >> RECT_BOUND_BITS; i <= (r->y2 - 1) >> RECT_BOUND_BITS; i++) { if (i >= *n) { struct table_cell ***ns; int *nnn; if ((unsigned)i > MAXINT / sizeof(struct table_cell ***) - 1) overalloc(); if ((unsigned)i > MAXINT / sizeof(int *) - 1) overalloc(); ns = mem_realloc(*s, (i + 1) * sizeof(struct table_cell ***)); nnn = mem_realloc(*nn, (i + 1) * sizeof(int *)); for (j = *n; j < i + 1; j++) ns[j] = DUMMY, nnn[j] = 0; *s = ns; *nn = nnn; *n = i + 1; } { struct table_cell **nc; if ((unsigned)(*nn)[i] > MAXINT / sizeof(struct table_cell *) - 1) overalloc(); nc = mem_realloc((*s)[i], ((*nn)[i] + 1) * sizeof(struct table_cell *)); nc[(*nn)[i]] = c; (*s)[i] = nc; (*nn)[i]++; } }}void table_mouse_event(struct f_data_c *fd, struct g_object_table *o, int x, int y, int b){ struct table *t = o->t; 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) if (g_forward_mouse(fd, (struct g_object *)c->root, x, y, b)) return; }}void draw_rect_set(struct graphics_device *dev, struct background *bg, struct rect_set *rs, int x, int y){ int i; for (i = 0; i < rs->m; i++) { struct rect *r = &rs->r[i]; if (is_rect_valid(r)) g_draw_background(dev, bg, x + r->x1, y + r->y1, r->x2 - r->x1, r->y2 - r->y1); }}void draw_rect_sets(struct graphics_device *dev, struct background *bg, struct rect_set **rs, int nrs, int x, int y){ int i; for (i = (dev->clip.y1 - y) >> RECT_BOUND_BITS; i <= (dev->clip.y2 - y - 1) >> RECT_BOUND_BITS; i++) if (i >= 0 && i < nrs) { draw_rect_set(dev, bg, rs[i], x, y); }}void table_draw(struct f_data_c *fd, struct g_object_table *o, int x, int y){ static int dgen = 1; int i, j; struct table *t = o->t; struct graphics_device *dev = fd->ses->term->dev; dgen++; /* for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) { struct table_cell *c = CELL(t, i, j);*/ /* fprintf(stderr, "Y: %d %d\n", x, y); fprintf(stderr, "bounds: %d %d\n", dev->clip.y1 + y, dev->clip.y2 + y); */ for (i = (dev->clip.y1 - y) >> RECT_BOUND_BITS; i <= (dev->clip.y2 - y - 1) >> RECT_BOUND_BITS; i++) if (i >= 0 && i < t->nr_cells) for (j = 0; j < t->w_cells[i]; j++) { struct table_cell *c = t->r_cells[i][j]; /*fprintf(stderr, "draw: %d %d\n", i, j);*/ if (c->root && c->dgen != dgen) { struct rect clip; memcpy(&clip, &c->rect, sizeof(struct rect)); clip.x1 += x; clip.x2 += x; clip.y1 += y; clip.y2 += y; if (!do_rects_intersect(&clip, &dev->clip)) continue; draw_rect_set(dev, c->root->bg, c->brd, x, y); restrict_clip_area(dev, &clip, x + c->root->x, y + c->root->y, x + c->root->x + c->root->xw/*c->g_width*/, y + c->root->y + c->root->yw); c->root->draw(fd, c->root, x + c->root->x, y + c->root->y); drv->set_clip_area(dev, &clip); c->dgen = dgen; } } draw_rect_sets(dev, t->bg, t->r_bg, t->nr_bg, x, y); draw_rect_sets(dev, t->frame_bg, t->r_frame, t->nr_frame, x, y);}void table_destruct(struct g_object_table *o){ free_table(o->t); mem_free(o);}void table_get_list(struct g_object_table *o, void (*fn)(struct g_object *parent, struct g_object *child)){ struct table *t = o->t; 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) fn((struct g_object *)o, (struct g_object *)c->root); }}void table_bg(struct text_attrib *ta, char bgstr[8]){ if (ta->bg.r + ta->bg.g * 3 + ta->bg.b * 5 > 9 * 128) strcpy(bgstr, "#000000"); else if (ta->fg.r > G_HTML_TABLE_FRAME_COLOR && ta->fg.g > G_HTML_TABLE_FRAME_COLOR && ta->fg.b > G_HTML_TABLE_FRAME_COLOR) { unsigned char max = ta->fg.r; if (ta->fg.g > max) max = ta->fg.g; if (ta->fg.b > max) max = ta->fg.b; max &= 0xff; sprintf(bgstr, "#%02x%02x%02x", max, max, max); } else sprintf(bgstr, "#%02x%02x%02x", G_HTML_TABLE_FRAME_COLOR, G_HTML_TABLE_FRAME_COLOR, G_HTML_TABLE_FRAME_COLOR);}void process_g_table(struct g_part *gp, struct table *t){ int i, j; int x, y; struct g_object_table *o; signed char *fv, *fh; unsigned char bgstr[8]; struct text_attrib *ta; struct rgb dummy; y = 0; for (j = 0; j < t->y; j++) { x = 0; y += g_get_hline_pad(t, j, NULL, NULL); for (i = 0; i < t->x; i++) { struct table_cell *c; x += g_get_vline_pad(t, i, NULL, NULL); c = CELL(t, i, j); if (c->root) { int s; int yw = 0; for (s = 0; s < c->rowspan; s++) { yw += t->r_heights[j + s]; if (s < c->rowspan - 1) yw += g_get_hline_pad(t, j + s + 1, NULL, NULL); } c->root->x = x, c->root->y = y; c->root->y += c->valign != VAL_MIDDLE && c->valign != VAL_BOTTOM ? 0 : (yw - c->root->yw) / (c->valign == VAL_MIDDLE ? 2 : 1); } x += t->w_c[i]; } y += t->r_heights[j]; } if (html_top.next != (struct html_element *)(void *)&html_stack) ta = &html_top.next->attr; else ta = &format; if (t->bordercolor && !decode_color(t->bordercolor, &dummy)) { if (!(t->frame_bg = get_background(NULL, t->bordercolor))) { free_table(t); return; } } else { table_bg(ta, bgstr); if (!(t->frame_bg = get_background(NULL, bgstr))) { free_table(t); return; } } if ((unsigned)t->x > MAXINT) overalloc(); if ((unsigned)t->y > MAXINT) overalloc(); if (((unsigned)t->x + 2) * ((unsigned)t->y + 2) / ((unsigned)t->x + 2) != ((unsigned)t->y + 2)) overalloc(); if (((unsigned)t->x + 2) * ((unsigned)t->y + 2) > MAXINT) overalloc(); fh = mem_alloc((t->x + 2) * (t->y + 1)); fv = mem_alloc((t->x + 1) * (t->y + 2)); get_table_frame(t, fv, fh); y = 0; for (j = 0; j <= t->y; j++) { int ypad, ypos, ysize; ypad = g_get_hline_pad(t, j, &ypos, &ysize); x = 0; for (i = 0; i <= t->x; i++) { struct rect r; int xpad, xpos, xsize; xpad = g_get_vline_pad(t, i, &xpos, &xsize); if (i < t->x && j < t->y) { CELL(t, i, j)->xpos = x + xpos + xsize; CELL(t, i, j)->ypos = y + ypos + ysize; } if (i > 0 && j > 0) { struct table_cell *c = CELL(t, i - 1, j - 1); c->xw = x + xpos - c->xpos; c->yw = y + ypos - c->ypos; /*debug("C: %d %d %d %d", c->xpos, c->ypos, c->xw, c->yw);*/ /*debug("%d %d %d", y, ypos, c->ypos);*/ if (!c->used && !c->spanned) { r.x1 = c->xpos, r.x2 = c->xpos + c->xw; r.y1 = c->ypos, r.y2 = c->ypos + c->yw; add_to_rect_sets(&t->r_bg, &t->nr_bg, &r); } } r.x1 = x + xpos, r.x2 = x + xpos + xsize; r.y1 = y + ypos, r.y2 = y + ypos + ysize; if (H_LINE(i-1,j) || H_LINE(i,j) || V_LINE(i,j-1) || V_LINE(i,j)) add_to_rect_sets(&t->r_frame, &t->nr_frame, &r); else if (H_LINE_X(i-1,j) != -2 || H_LINE_X(i,j) != -2 || V_LINE_X(i,j-1) != -2 || V_LINE_X(i,j) != -2) add_to_rect_sets(&t->r_bg, &t->nr_bg, &r); if (i < t->x) { int l; int b; g_get_vline_pad(t, i + 1, &b, NULL); r.x1 = r.x2; r.x2 = x + xpad + t->w_c[i] + b; l = H_LINE_X(i,j); if (l == -2) ; else if (l > 0) add_to_rect_sets(&t->r_frame, &t->nr_frame, &r); else add_to_rect_sets(&t->r_bg, &t->nr_bg, &r); } r.x1 = x + xpos, r.x2 = x + xpos + xsize; if (j < t->y) { int l; int b; g_get_hline_pad(t, j + 1, &b, NULL); r.y1 = r.y2; r.y2 = y + ypad + t->r_heights[j] + b; l = V_LINE_X(i,j); if (l == -2) ; else if (l > 0) add_to_rect_sets(&t->r_frame, &t->nr_frame, &r); else add_to_rect_sets(&t->r_bg, &t->nr_bg, &r); } if (i < t->x) x += xpad + t->w_c[i]; } if (j < t->y) y += ypad + t->r_heights[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->used && !c->spanned && c->root) { struct table_cell *d = CELL(t, i + c->colspan - 1, j + c->rowspan - 1); struct rect r; r.x1 = c->xpos; r.y1 = c->ypos; r.x2 = d->xpos + d->xw; r.y2 = d->ypos + d->yw; add_to_cell_sets(&t->r_cells, &t->w_cells, &t->nr_cells, &r, c); memcpy(&c->rect, &r, sizeof(struct rect)); c->brd = init_rect_set(); /*debug("%d,%d %d,%d", r.x1, r.y1, r.x2, r.y2);*/ add_to_rect_set(&c->brd, &r); r.x1 = c->root->x; r.y1 = c->root->y; r.x2 = c->root->x + c->root->xw; r.y2 = c->root->y + c->root->yw; exclude_rect_from_set(&c->brd, &r); /*debug("%d,%d %d,%d", r.x1, r.y1, r.x2, r.y2);*/ } } mem_free(fh); mem_free(fv); o = mem_calloc(sizeof(struct g_object_table)); o->mouse_event = table_mouse_event; o->draw = table_draw; o->destruct = table_destruct; o->get_list = table_get_list; o->xw = t->rw; o->yw = t->rh; o->t = t; t->bg = gp->root->bg; flush_pending_text_to_line(gp); flush_pending_line_to_obj(gp, 0); gp->cx = -1; add_object_to_line(gp, &gp->line, (struct g_object *)o); flush_pending_text_to_line(gp); par_format.align = t->align; flush_pending_line_to_obj(gp, 0); gp->cx = -1;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -