📄 html_r.c
字号:
static int bg_cache; static int fg_cache; int bg, fg; int i; struct link *link; struct point *pt; if (l < 0) overalloc(); /*printf("%d-", p->cx);for (i=0; i<l; i++) printf("%c", c[i]); printf("-\n");sleep(1);*/ while (par_format.align != AL_NO && p->cx == -1 && l && *c == ' ') c++, l--; if (!l) return; if (c[0] != ' ' || (c[1] && c[1] != ' ')) { last_tag_for_newline = (void *)&p->data->tags; } if (p->cx < par_format.leftmargin) p->cx = par_format.leftmargin; if (last_link || last_image || last_form || format.link || format.image || format.form) goto process_link; no_l: /*printf("%d %d\n",p->cx, p->cy);*/ if (memcmp(&ta_cache, &format, sizeof(struct text_attrib_beginning))) goto format_change; bg = bg_cache, fg = fg_cache; end_format_change: if (p->cx == par_format.leftmargin && *c == ' ' && par_format.align != AL_NO) c++, l--; if (p->y < p->cy + 1) p->y = p->cy + 1; if (nowrap && p->cx + l > rm(par_format)) return; set_hline(p, p->cx, p->cy, l, c, (((fg&0x08)<<3)|(bg<<3)|(fg&0x07))<<8, 1); p->cx += l; nobreak = 0; if (par_format.align != AL_NO) while (p->cx > rm(par_format) && p->cx > par_format.leftmargin) { int x; /*if (p->cx > p->x) { p->x = p->cx + par_format.rightmargin; if (c[l - 1] == ' ') p->x--; }*/ if (!(x = split_line(p))) break; /*if (LEN(p->cy-1) > p->x) p->x = LEN(p->cy-1);*/ align_line(p, p->cy - 1); nobreak = x - 1; } if ((p->xa += l) - (c[l-1] == ' ' && par_format.align != AL_NO) + par_format.leftmargin + par_format.rightmargin > p->xmax) p->xmax = p->xa - (c[l-1] == ' ' && par_format.align != AL_NO) + par_format.leftmargin + par_format.rightmargin; return; process_link: if ((last_link /*|| last_target*/ || last_image || last_form) && !xstrcmp(format.link, last_link) && !xstrcmp(format.target, last_target) && !xstrcmp(format.image, last_image) && format.form == last_form) { if (!p->data) goto x; link = &p->data->links[p->data->nlinks - 1]; if (!p->data->nlinks) { internal("no link"); goto no_l; } goto set_link; x:; } else { if (last_link) mem_free(last_link); /* !!! FIXME: optimize */ if (last_target) mem_free(last_target); if (last_image) mem_free(last_image); last_link = last_target = last_image = NULL; last_form = NULL; if (!(format.link || format.image || format.form)) goto no_l; if (d_opt->num_links) { unsigned char s[64]; unsigned char *fl = format.link, *ft = format.target, *fi = format.image; struct form_control *ff = format.form; format.link = format.target = format.image = NULL; format.form = NULL; s[0] = '['; snzprint(s + 1, 62, p->link_num); strcat(s, "]"); put_chars(p, s, strlen(s)); if (ff && ff->type == FC_TEXTAREA) line_break(p); if (p->cx == -1) p->cx = par_format.leftmargin; format.link = fl, format.target = ft, format.image = fi; format.form = ff; } p->link_num++; last_link = stracpy(format.link); last_target = stracpy(format.target); last_image = stracpy(format.image); last_form = format.form; if (!p->data) goto no_l; if (!(link = new_link(p->data))) goto no_l; link->num = p->link_num - 1; link->pos = DUMMY; if (!last_form) { link->type = L_LINK; link->where = stracpy(last_link); link->target = stracpy(last_target); } else { link->type = last_form->type == FC_TEXT || last_form->type == FC_PASSWORD || last_form->type == FC_FILE ? L_FIELD : last_form->type == FC_TEXTAREA ? L_AREA : last_form->type == FC_CHECKBOX || last_form->type == FC_RADIO ? L_CHECKBOX : last_form->type == FC_SELECT ? L_SELECT : L_BUTTON; link->form = last_form; link->target = stracpy(last_form->target); } link->where_img = stracpy(last_image); if (link->type != L_FIELD && link->type != L_AREA) { bg = find_nearest_color(&format.clink, 8); fg = find_nearest_color(&format.bg, 8); fg = fg_color(fg, bg); } else { fg = find_nearest_color(&format.fg, 8); bg = find_nearest_color(&format.bg, 8); fg = fg_color(fg, bg); } link->sel_color = ((fg & 8) << 3) | (fg & 7) | (bg << 3); link->n = 0; set_link: if ((unsigned)link->n + (unsigned)l > MAXINT / sizeof(struct point)) overalloc(); pt = mem_realloc(link->pos, (link->n + l) * sizeof(struct point)); link->pos = pt; for (i = 0; i < l; i++) pt[link->n + i].x = X(p->cx) + i, pt[link->n + i].y = Y(p->cy); link->n += l; } goto no_l; format_change: bg = find_nearest_color(&format.bg, 8); fg = find_nearest_color(&format.fg, 16); fg = fg_color(fg, bg); if (format.attr & AT_ITALIC) fg = fg ^ 0x01; if (format.attr & AT_UNDERLINE) fg = (fg ^ 0x04) | 0x08; if (format.attr & AT_BOLD) fg = fg | 0x08; fg = fg_color(fg, bg); if (format.attr & AT_GRAPHICS) bg = bg | 0x10; memcpy(&ta_cache, &format, sizeof(struct text_attrib_beginning)); fg_cache = fg; bg_cache = bg; goto end_format_change;}void line_break(struct part *p){ struct tag *t; /*printf("-break-\n");*/ if (p->cx + par_format.rightmargin > p->x) p->x = p->cx + par_format.rightmargin; if (nobreak) { /*if (p->y < p->cy) p->y = p->cy;*/ nobreak = 0; p->cx = -1; p->xa = 0; return; } if (!p->data) goto e; /*move_links(p, p->cx, p->cy, 0, p->cy + 1);*/ xpand_lines(p, p->cy + 1); if (p->cx > par_format.leftmargin && LEN(p->cy) > p->cx - 1 && (POS(p->cx-1, p->cy) & 0xff) == ' ') del_chars(p, p->cx-1, p->cy), p->cx--; /*if (LEN(p->cy) > p->x) p->x = LEN(p->cy);*/ if (p->cx > 0) align_line(p, p->cy); if (p->data) for (t = last_tag_for_newline; t && (void *)t != &p->data->tags; t = t->prev) { t->x = X(0); t->y = Y(p->cy + 1); } e: p->cy++; p->cx = -1; p->xa = 0; /*if (p->y < p->cy) p->y = p->cy;*/ memset(p->spaces, 0, p->spl);}int g_ctrl_num;void html_form_control(struct part *p, struct form_control *fc){ if (!p->data) { /*destroy_fc(fc); mem_free(fc);*/ add_to_list(p->uf, fc); return; } fc->g_ctrl_num = g_ctrl_num++; if (fc->type == FC_TEXT || fc->type == FC_PASSWORD || fc->type == FC_TEXTAREA) { unsigned char *dv = convert_string(convert_table, fc->default_value, strlen(fc->default_value)); if (dv) { mem_free(fc->default_value); fc->default_value = dv; } /* for (i = 0; i < fc->nvalues; i++) if ((dv = convert_string(convert_table, fc->values[i], strlen(fc->values[i])))) { mem_free(fc->values[i]); fc->values[i] = dv; } */ } if (fc->type == FC_TEXTAREA) { unsigned char *p; for (p = fc->default_value; p[0]; p++) if (p[0] == '\r') { if (p[1] == '\n') memmove(p, p + 1, strlen(p)), p--; else p[0] = '\n'; } } add_to_list(p->data->forms, fc);}void add_frameset_entry(struct frameset_desc *fsd, struct frameset_desc *subframe, unsigned char *name, unsigned char *url){ if (fsd->yp >= fsd->y) return; fsd->f[fsd->xp + fsd->yp * fsd->x].subframe = subframe; fsd->f[fsd->xp + fsd->yp * fsd->x].name = stracpy(name); fsd->f[fsd->xp + fsd->yp * fsd->x].url = stracpy(url); if (++fsd->xp >= fsd->x) fsd->xp = 0, fsd->yp++;}struct frameset_desc *create_frameset(struct f_data *fda, struct frameset_param *fp){ int i; struct frameset_desc *fd; if (!fp->x || !fp->y) { internal("zero size of frameset"); return NULL; } if (fp->x && (unsigned)fp->x * (unsigned)fp->y / (unsigned)fp->x != (unsigned)fp->y) overalloc(); if ((unsigned)fp->x * (unsigned)fp->y > (MAXINT - sizeof(struct frameset_desc)) / sizeof(struct frame_desc)) overalloc(); fd = mem_alloc(sizeof(struct frameset_desc) + fp->x * fp->y * sizeof(struct frame_desc)); memset(fd, 0, sizeof(struct frameset_desc) + fp->x * fp->y * sizeof(struct frame_desc)); fd->n = fp->x * fp->y; fd->x = fp->x; fd->y = fp->y; for (i = 0; i < fd->n; i++) { fd->f[i].xw = fp->xw[i % fp->x]; fd->f[i].yw = fp->yw[i / fp->x]; } if (fp->parent) add_frameset_entry(fp->parent, fd, NULL, NULL); else if (!fda->frame_desc) fda->frame_desc = fd; else mem_free(fd), fd = NULL; return fd;}void create_frame(struct frame_param *fp){ add_frameset_entry(fp->parent, NULL, fp->name, fp->url);}void *html_special(struct part *p, int c, ...){ va_list l; unsigned char *t; struct form_control *fc; struct frameset_param *fsp; struct frame_param *fp; va_start(l, c); switch (c) { case SP_TAG: t = va_arg(l, unsigned char *); va_end(l); html_tag(p->data, t, X(p->cx), Y(p->cy)); break; case SP_CONTROL: fc = va_arg(l, struct form_control *); va_end(l); html_form_control(p, fc); break; case SP_TABLE: va_end(l); return convert_table; case SP_USED: va_end(l); return (void *)!!p->data; case SP_FRAMESET: fsp = va_arg(l, struct frameset_param *); va_end(l); return create_frameset(p->data, fsp); case SP_FRAME: fp = va_arg(l, struct frame_param *); va_end(l); create_frame(fp); break; case SP_NOWRAP: nowrap = va_arg(l, int); va_end(l); break; default: internal("html_special: unknown code %d", c); va_end(l); } return NULL;}void do_format(char *start, char *end, struct part *part, unsigned char *head){ parse_html(start, end, (int (*)(void *, unsigned char *, int)) put_chars_conv, (void (*)(void *)) line_break, (void *(*)(void *, int, ...)) html_special, part, head); /*if ((part->y -= line_breax) < 0) part->y = 0;*/}int margin;struct table_cache_entry { struct table_cache_entry *next; struct table_cache_entry *prev; struct table_cache_entry *hash_next; unsigned char *start; unsigned char *end; int align; int m; int width; int xs; int link_num; struct part p;};struct list_head table_cache = { &table_cache, &table_cache };#define TC_HASH_SIZE 4096struct table_cache_entry *table_cache_hash[TC_HASH_SIZE];void free_table_cache(){ struct table_cache_entry *tce; foreach(tce, table_cache) { int hash = ((int)(unsigned long)tce->start + tce->xs) & (TC_HASH_SIZE - 1); table_cache_hash[hash] = NULL; } free_list(table_cache);}struct part *format_html_part(unsigned char *start, unsigned char *end, int align, int m, int width, struct f_data *data, int xs, int ys, unsigned char *head, int link_num){ struct part *p; struct html_element *e; int llm = last_link_to_move; struct tag *ltm = last_tag_to_move; /*struct tag *ltn = last_tag_for_newline;*/ int lm = margin; int ef = empty_format; struct form_control *fc; struct table_cache_entry *tce; if (!data) { tce = table_cache_hash[((int)(unsigned long)start + xs) & (TC_HASH_SIZE - 1)]; while (tce) { if (tce->start == start && tce->end == end && tce->align == align && tce->m == m && tce->width == width && tce->xs == xs && tce->link_num == link_num) { p = mem_alloc(sizeof(struct part)); memcpy(p, &tce->p, sizeof(struct part)); return p; } tce = tce->hash_next; } } if (ys < 0) { internal("format_html_part: ys == %d", ys); return NULL; } if (data) { struct node *n; n = mem_alloc(sizeof(struct node)); n->x = xs; n->y = ys; n->xw = !table_level ? MAXINT : width; add_to_list(data->nodes, n); /*sdbg(data);*/ } last_link_to_move = data ? data->nlinks : 0; last_tag_to_move = data ? (void *)&data->tags : NULL; last_tag_for_newline = data ? (void *)&data->tags: NULL; margin = m; empty_format = !data; if (last_link) mem_free(last_link); if (last_image) mem_free(last_image); if (last_target) mem_free(last_target); last_link = last_image = last_target = NULL; last_form = NULL; nobreak = 1; p = mem_alloc(sizeof(struct part)); p->x = p->y = 0; p->data = data; p->xp = xs; p->yp = ys; p->xmax = p->xa = 0; p->bgcolor = find_nearest_color(&par_format.bgcolor, 8); p->spaces = DUMMY; p->spl = 0; p->link_num = link_num; init_list(p->uf); html_stack_dup(); e = &html_top; html_top.dontkill = 2; html_top.namelen = 0; par_format.align = align; par_format.leftmargin = m; par_format.rightmargin = m; par_format.width = width; par_format.list_level = 0; par_format.list_number = 0; par_format.dd_margin = 0; p->cx = -1; p->cy = 0; do_format(start, end, p, head); if (p->xmax < p->x) p->xmax = p->x; nobreak = 0; line_breax = 1; if (last_link) mem_free(last_link); if (last_image) mem_free(last_image); if (last_target) mem_free(last_target); while (&html_top != e) { kill_html_stack_item(&html_top); if (!&html_top || (void *)&html_top == (void *)&html_stack) { internal("html stack trashed"); break; } } html_top.dontkill = 0; kill_html_stack_item(&html_top); mem_free(p->spaces); if (data) { struct node *n = data->nodes.next; n->yw = ys - n->y + p->y; } foreach(fc, p->uf) destroy_fc(fc); free_list(p->uf); last_link_to_move = llm; last_tag_to_move = ltm; /*last_tag_for_newline = ltn;*/ margin = lm; empty_format = ef; last_link = last_image = last_target = NULL; last_form = NULL; if (table_level > 1 && !data) { int hash; tce = mem_alloc(sizeof(struct table_cache_entry)); tce->start = start; tce->end = end; tce->align = align; tce->m = m; tce->width = width; tce->xs = xs; tce->link_num = link_num; memcpy(&tce->p, p, sizeof(struct part)); add_to_list(table_cache, tce); hash = ((int)(unsigned long)start + xs) & (TC_HASH_SIZE - 1); tce->hash_next = table_cache_hash[hash]; table_cache_hash[hash] = tce; } return p;}void push_base_format(unsigned char *url, struct document_options *opt){ struct html_element *e; if (html_stack.next != &html_stack) { internal("something on html stack"); init_list(html_stack); } e = mem_alloc(sizeof(struct html_element)); memset(e, 0, sizeof(struct html_element)); add_to_list(html_stack, e); format.attr = 0; format.fontsize = 3; format.link = format.target = format.image = format.select = NULL; format.form = NULL; memcpy(&format.fg, &opt->default_fg, sizeof(struct rgb)); memcpy(&format.bg, &opt->default_bg, sizeof(struct rgb)); memcpy(&format.clink, &opt->default_link, sizeof(struct rgb)); memcpy(&format.vlink, &opt->default_vlink, sizeof(struct rgb)); format.href_base = stracpy(url); format.target_base = stracpy(opt->framename); par_format.align = opt->plain ? AL_NO : AL_LEFT; par_format.leftmargin = opt->plain ? 0 : opt->margin; par_format.rightmargin = opt->plain ? 0 : opt->margin; par_format.width = opt->xw; par_format.list_level = par_format.list_number = 0; par_format.dd_margin = opt->margin; par_format.flags = 0; memcpy(&par_format.bgcolor, &opt->default_bg, sizeof(struct rgb)); html_top.invisible = 0; html_top.name = NULL; html_top.namelen = 0; html_top.options = NULL; html_top.linebreak = 1; html_top.dontkill = 1;}struct conv_table *get_convert_table(unsigned char *head, int to, int def, int *frm, int *aa, int hard){ int from = -1; unsigned char *a, *b; unsigned char *p = head; while (from == -1 && p && (a = parse_http_header(p, "Content-Type", &p))) { if ((b = parse_header_param(a, "charset"))) { from = get_cp_index(b); mem_free(b); } mem_free(a); } if (from == -1 && head && (a = parse_http_header(head, "Content-Charset", NULL))) { from = get_cp_index(a); mem_free(a); } if (from == -1 && head && (a = parse_http_header(head, "Charset", NULL))) { from = get_cp_index(a); mem_free(a); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -