📄 html_r.c
字号:
va_end(l); html_process_refresh(p->data, rp->url, rp->time); break; case SP_SET_BASE: t = va_arg(l, unsigned char *); va_end(l); if (p->data) set_base(p->data, t); break; default: va_end(l); internal("html_special: unknown code %d", c); } return NULL;}void do_format(char *start, char *end, struct part *part, unsigned char *head){ pr( 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); free_js_event_spec(last_js_event); last_link = last_image = last_target = NULL; last_form = NULL; last_js_event = 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); free_js_event_spec(last_js_event); 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; last_js_event = 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 release_part(struct part *p){ mem_free(p);}void push_base_format(unsigned char *url, struct document_options *opt, int frame){ struct html_element *e; if (html_stack.next != &html_stack) { internal("something on html stack"); init_list(html_stack); } e = mem_calloc(sizeof(struct html_element)); add_to_list(html_stack, e); format.attr = opt->plain & 1 ? AT_FIXED : 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 & 1 ? AL_NO : AL_LEFT; par_format.leftmargin = opt->plain & 1 ? 0 : opt->margin; par_format.rightmargin = opt->plain & 1 ? 0 : opt->margin; if (frame && par_format.leftmargin) par_format.leftmargin = 1; if (frame && par_format.rightmargin) par_format.rightmargin = 1; 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); } if (aa) { *aa = from == -1; if (hard && !*aa) *aa = 2; } if (hard || from == -1) from = def; if (frm) *frm = from; return get_translation_table(from, to);}struct document_options dd_opt;struct document_options *d_opt = &dd_opt;struct f_data *current_f_data = NULL;void really_format_html(struct cache_entry *ce, unsigned char *start, unsigned char *end, struct f_data *screen, int frame){ unsigned char *url = ce->url; unsigned char *head, *t; int hdl; int i; unsigned char *bg = NULL, *bgcolor = NULL; current_f_data = screen; memset(table_cache_hash, 0, sizeof(table_cache_hash)); d_opt = &screen->opt; screen->use_tag = ce->count; startf = start; eofff = end; head = init_str(), hdl = 0; if (ce->head) add_to_str(&head, &hdl, ce->head); scan_http_equiv(start, end, &head, &hdl, &t, d_opt->plain ? NULL : &bg, d_opt->plain ? NULL : &bgcolor, &screen->js_event); convert_table = get_convert_table(head, screen->opt.cp, screen->opt.assume_cp, &screen->cp, &screen->ass, screen->opt.hard_assume); screen->opt.real_cp = screen->cp; i = d_opt->plain; d_opt->plain = 0; screen->title = convert_string(convert_table, t, strlen(t), d_opt); d_opt->plain = i; mem_free(t); push_base_format(url, &screen->opt, frame); table_level = 0; g_ctrl_num = 0; last_form_tag = NULL; last_form_attr = NULL; last_input_tag = NULL; if (!F) { struct part *rp; if ((rp = format_html_part(start, end, par_format.align, par_format.leftmargin, screen->opt.xw, screen, 0, 0, head, 1))) release_part(rp);#ifdef G } else { struct g_part *rp; if ((rp = g_format_html_part(start, end, par_format.align, par_format.leftmargin, screen->opt.xw - G_SCROLL_BAR_WIDTH, head, 1, bg, bgcolor, screen))) { int w = screen->opt.xw; int h = screen->opt.yw; screen->x = rp->x; screen->y = rp->root->yw; if (screen->x > w) w = screen->x; if (screen->y > h) h = screen->y; g_x_extend_area(rp->root, w, h); screen->root = (struct g_object *)rp->root, rp->root = NULL; screen->hsb = 0, screen->vsb = 0; screen->hsbsize = 0, screen->vsbsize = 0; if (screen->opt.scrolling == SCROLLING_YES) { screen->hsb = 1, screen->vsb = 1; } else if (screen->opt.scrolling == SCROLLING_AUTO) { x: if (!screen->hsb && screen->x > screen->opt.xw - screen->vsb * G_SCROLL_BAR_WIDTH) { screen->hsb = 1; goto x; } if (!screen->vsb && screen->y > screen->opt.yw - screen->hsb * G_SCROLL_BAR_WIDTH) { screen->vsb = 1; goto x; } } if (screen->hsb) screen->hsbsize = screen->opt.xw - screen->vsb * G_SCROLL_BAR_WIDTH; if (screen->vsb) screen->vsbsize = screen->opt.yw - screen->hsb * G_SCROLL_BAR_WIDTH; if (screen->hsb < 0) screen->hsb = 0; if (screen->vsb < 0) screen->vsb = 0; g_release_part(rp); mem_free(rp); get_parents(screen, screen->root); }#endif } mem_free(head); if (bg) mem_free(bg); if (bgcolor) mem_free(bgcolor); if (!F) { screen->x = 0; for (i = screen->y - 1; i >= 0; i--) { if (!screen->data[i].l) mem_free(screen->data[i].d), screen->y--; else break; } for (i = 0; i < screen->y; i++) if (screen->data[i].l > screen->x) screen->x = screen->data[i].l; } if (form.action) mem_free(form.action), form.action = NULL; if (form.target) mem_free(form.target), form.target = NULL; if (form.form_name) mem_free(form.form_name), form.form_name = NULL; if (form.onsubmit) mem_free(form.onsubmit), form.onsubmit = NULL; kill_html_stack_item(html_stack.next); if (html_stack.next != &html_stack) { internal("html stack not empty after operation"); init_list(html_stack); } screen->bg = 007 << 8; /* !!! FIXME */ sort_links(screen); current_f_data = NULL; d_opt = &dd_opt;}int compare_opt(struct document_options *o1, struct document_options *o2){ double kdo_si_hraje_nezlobi____a_nebo_to_je_PerM=o1->bfu_aspect-o2->bfu_aspect; if (o1->xw == o2->xw && o1->yw == o2->yw && o1->xp == o2->xp && o1->yp == o2->yp && o1->scrolling == o2->scrolling && o1->col == o2->col && o1->cp == o2->cp && o1->assume_cp == o2->assume_cp && o1->hard_assume == o2->hard_assume && o1->braille == o2->braille && o1->tables == o2->tables && o1->frames == o2->frames && o1->images == o2->images && o1->image_names == o2->image_names && o1->margin == o2->margin && o1->js_enable == o2->js_enable && o1->plain == o2->plain && o1->num_links == o2->num_links && o1->table_order == o2->table_order && o1->auto_refresh == o2->auto_refresh && o1->font_size == o2->font_size && o1->display_images == o2->display_images && o1->image_scale == o2->image_scale && o1->porn_enable == o2->porn_enable && o1->aspect_on == o2->aspect_on && !memcmp(&o1->default_fg, &o2->default_fg, sizeof(struct rgb)) && !memcmp(&o1->default_bg, &o2->default_bg, sizeof(struct rgb)) && !memcmp(&o1->default_link, &o2->default_link, sizeof(struct rgb)) && !memcmp(&o1->default_vlink, &o2->default_vlink, sizeof(struct rgb)) && kdo_si_hraje_nezlobi____a_nebo_to_je_PerM<=0.0001 && kdo_si_hraje_nezlobi____a_nebo_to_je_PerM>=-0.0001 && ((o1->framename && o2->framename && !strcasecmp(o1->framename, o2->framename)) || (!o1->framename && !o2->framename))) return 0; return 1;}void copy_opt(struct document_options *o1, struct document_options *o2){ memcpy(o1, o2, sizeof(struct document_options)); o1->framename = stracpy(o2->framename);}void add_srch_chr(struct f_data *f, unsigned char c, int x, int y, int nn){ int n = f->nsearch; if (c == ' ' && (!n || f->search[n - 1].c == ' ')) return; f->search[n].c = c; f->search[n].x = x; f->search[n].y = y; f->search[n].n = nn; f->nsearch++;}/*void sdbg(struct f_data *f){ struct node *n; foreachback(n, f->nodes) { int xm = n->x + n->xw, ym = n->y + n->yw; printf("%d %d - %d %d\n", n->x, n->y, xm, ym); fflush(stdout); } debug("!");}*/void sort_srch(struct f_data *f){ int i; int *min, *max; if ((unsigned)f->y > MAXINT / sizeof(struct search *)) overalloc(); if ((unsigned)f->y > MAXINT / sizeof(int)) overalloc(); f->slines1 = mem_calloc(f->y * sizeof(struct search *)); f->slines2 = mem_calloc(f->y * sizeof(struct search *)); min = mem_alloc(f->y * sizeof(int)); max = mem_alloc(f->y * sizeof(int)); for (i = 0; i < f->y; i++) min[i] = MAXINT, max[i] = 0; for (i = 0; i < f->nsearch; i++) { struct search *s = &f->search[i]; if (s->x < min[s->y]) min[s->y] = s->x, f->slines1[s->y] = s; if (s->x + s->n > max[s->y]) max[s->y] = s->x + s->n, f->slines2[s->y] = s; } mem_free(min); mem_free(max);}static inline int is_spc(chr c){ return (unsigned char)c <= ' ' || c & ATTR_FRAME;}int get_srch(struct f_data *f){ struct node *n; int cnt = 0; int cc = !f->search; foreachback(n, f->nodes) { int x, y; int xm = n->x + n->xw, ym = n->y + n->yw; /*printf("%d %d - %d %d\n", n->x, n->y, xm, ym); fflush(stdout);*/ for (y = n->y; y < ym && y < f->y; y++) { int ns = 1; for (x = n->x; x < xm && x < f->data[y].l; x++) { unsigned char c = f->data[y].d[x]; if (is_spc(f->data[y].d[x])) c = ' '; if (c == ' ' && ns) continue; c = charset_upcase(c, f->opt.cp); if (ns) { if (!cc) add_srch_chr(f, c, x, y, 1); else cnt++; ns = 0; continue; } if (c != ' ') if (!cc) add_srch_chr(f, c, x, y, 1); else cnt++; else { int xx; for (xx = x + 1; xx < xm && xx < f->data[y].l; xx++) if (!is_spc(f->data[y].d[xx])) goto ja_uz_z_toho_programovani_asi_zcvoknu; xx = x; ja_uz_z_toho_programovani_asi_zcvoknu: if (!cc) add_srch_chr(f, ' ', x, y, xx - x); else cnt++; if (xx == x) goto uz_jsem_zcvoknul__jsem_psychopat__trpim_poruchou_osobnosti; x = xx - 1; } } uz_jsem_zcvoknul__jsem_psychopat__trpim_poruchou_osobnosti: if (!cc) add_srch_chr(f, ' ', x, y, 0); else cnt++; } } return cnt; }void get_search_data(struct f_data *f){ int n; if (f->search) return; n = get_srch(f); f->nsearch = 0; if ((unsigned)n > MAXINT / sizeof(struct search)) overalloc(); f->search = mem_alloc(n * sizeof(struct search)); get_srch(f); while (f->nsearch && f->search[f->nsearch - 1].c == ' ') f->nsearch--; /*debug("!");*/ sort_srch(f);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -