📄 html_r.c
字号:
SLEN(y, x); move_links(p, x, y, -1, -1);}#define rm(x) ((x).width - (x).rightmargin > 0 ? (x).width - (x).rightmargin : 0)void line_break(struct part *);int split_line(struct part *p){ int i; /*if (!p->data) goto r;*/ /*printf("split: %d,%d , %d,%d,%d\n",p->cx,p->cy,par_format.rightmargin,par_format.leftmargin,p->cx);*/ for (i = rm(par_format); i >= par_format.leftmargin; i--) if (i < p->spl && p->spaces[i]) goto split; /*for (i = p->cx - 1; i > rm(par_format) && i > par_format.leftmargin; i--)*/ for (i = par_format.leftmargin; i < p->cx ; i++) if (i < p->spl && p->spaces[i]) goto split; /*for (i = rm(par_format); i >= par_format.leftmargin; i--) if ((POS(i, p->cy) & 0xff) == ' ') goto split; for (i = p->cx - 1; i > rm(par_format) && i > par_format.leftmargin; i--) if ((POS(i, p->cy) & 0xff) == ' ') goto split;*/ if (p->cx + par_format.rightmargin > p->x) p->x = p->cx + par_format.rightmargin; /*if (p->y < p->cy + 1) p->y = p->cy + 1; p->cy++; p->cx = -1; memset(p->spaces, 0, p->spl); if (p->data) xpand_lines(p, p->cy + 1);*/ /*line_break(p);*/ return 0; split: if (i + par_format.rightmargin > p->x) p->x = i + par_format.rightmargin; if (p->data) {#ifdef DEBUG if ((POS(i, p->cy) & 0xff) != ' ') internal("bad split: %c", (char)POS(i, p->cy));#endif move_chars(p, i+1, p->cy, par_format.leftmargin, p->cy+1); del_chars(p, i, p->cy); } memmove(p->spaces, p->spaces + i + 1, p->spl - i - 1); memset(p->spaces + p->spl - i - 1, 0, i + 1); memmove(p->spaces + par_format.leftmargin, p->spaces, p->spl - par_format.leftmargin); p->cy++; p->cx -= i - par_format.leftmargin + 1; /*return 1 + (p->cx == par_format.leftmargin);*/ if (p->cx == par_format.leftmargin) p->cx = -1; if (p->y < p->cy + (p->cx != -1)) p->y = p->cy + (p->cx != -1); return 1 + (p->cx == -1);}void align_line(struct part *p, int y){ int na; if (!p->data) return; if (!LEN(y) || par_format.align == AL_LEFT || par_format.align == AL_NO || par_format.align == AL_BLOCK /* !!! fixme! */) return; na = rm(par_format) - LEN(y); if (par_format.align == AL_CENTER) na /= 2; if (na > 0) shift_chars(p, y, na);}struct link *new_link(struct f_data *f){ if (!f) return NULL; if (!(f->nlinks & (ALLOC_GR - 1))) { if ((unsigned)f->nlinks > MAXINT / sizeof(struct link) - ALLOC_GR) overalloc(); f->links = mem_realloc(f->links, (f->nlinks + ALLOC_GR) * sizeof(struct link)); } memset(&f->links[f->nlinks], 0, sizeof(struct link));#ifdef G f->links[f->nlinks].r.x1 = MAXINT; f->links[f->nlinks].r.y1 = MAXINT;#endif return &f->links[f->nlinks++];}void html_tag(struct f_data *f, unsigned char *t, int x, int y){ struct tag *tag; unsigned char *tt; int ll; if (!f) return; tt = init_str(); ll = 0; add_conv_str(&tt, &ll, t, strlen(t), -2); tag = mem_alloc(sizeof(struct tag) + strlen(tt) + 1); tag->x = x; tag->y = y; strcpy(tag->name, tt); add_to_list(f->tags, tag); if ((void *)last_tag_for_newline == &f->tags) last_tag_for_newline = tag; mem_free(tt);}unsigned char *last_link = NULL;unsigned char *last_target = NULL;unsigned char *last_image = NULL;struct form_control *last_form = NULL;struct js_event_spec *last_js_event = NULL;int nobreak;struct conv_table *convert_table;void put_chars(struct part *, unsigned char *, int);#define CH_BUF 256int put_chars_conv(struct part *p, unsigned char *c, int l){ static char buffer[CH_BUF]; int bp = 0; int pp = 0; int total = 0; if (format.attr & AT_GRAPHICS) { put_chars(p, c, l); return l; } if (!l) put_chars(p, NULL, 0); while (pp < l) { unsigned char *e; if (c[pp] < 128 && c[pp] != '&') { putc: buffer[bp++] = c[pp++]; if (bp < CH_BUF) continue; goto flush; } if (c[pp] != '&') { struct conv_table *t; int i; if (!convert_table) goto putc; t = convert_table; i = pp; decode: if (!t[c[i]].t) { e = t[c[i]].u.str; } else { t = t[c[i++]].u.tbl; if (i >= l) goto putc; goto decode; } pp = i + 1; } else { int i = pp + 1; if (d_opt->plain & 1) goto putc; while (i < l && c[i] != ';' && c[i] != '&' && c[i] > ' ') i++; if (!(e = get_entity_string(&c[pp + 1], i - pp - 1, d_opt->cp))) goto putc; pp = i + (i < l && c[i] == ';'); } if (!e[0]) continue; if (!e[1]) { buffer[bp++] = e[0]; if (bp < CH_BUF) continue; flush: e = ""; goto flush1; } while (*e) { buffer[bp++] = *(e++); if (bp < CH_BUF) continue; flush1: put_chars(p, buffer, bp); total += bp; bp = 0; } } if (bp) put_chars(p, buffer, bp); total += bp; return total;}void put_chars(struct part *p, unsigned char *c, int l){ static struct text_attrib_beginning ta_cache = { -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0 }; 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 || format.js_event || last_js_event ) 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; /* !!! WARNING: THE FOLLOWING CODE IS SHADOWED IN HTML_GR.C */ 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 && ((!format.js_event && !last_js_event) || !compare_js_event_spec(format.js_event, last_js_event)) ) { 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); if (last_target) mem_free(last_target); if (last_image) mem_free(last_image); free_js_event_spec(last_js_event); last_link = last_target = last_image = NULL; last_form = NULL; last_js_event = NULL; if (!(format.link || format.image || format.form || format.js_event)) goto no_l; if (d_opt->num_links || d_opt->braille) { unsigned char s[64]; unsigned char *fl = format.link, *ft = format.target, *fi = format.image; struct form_control *ff = format.form; struct js_event_spec *js = format.js_event; format.link = format.target = format.image = NULL; format.form = NULL; format.js_event = NULL; if (d_opt->num_links) { s[0] = '['; snzprint(s + 1, 62, p->link_num); strcat(s, "]"); } else { if (ff && (ff->type == FC_TEXT || ff->type == FC_PASSWORD || ff->type == FC_FILE || ff->type == FC_TEXTAREA)) { strcpy(s, ">"); } else if (ff && (ff->type == FC_CHECKBOX || ff->type == FC_RADIO || ff->type == FC_SELECT)) { strcpy(s, ""); } else { strcpy(s, "~"); } } put_chars(p, s, strlen(s)); if (ff && ff->type == FC_TEXTAREA) line_break(p); if (p->cx < par_format.leftmargin) p->cx = par_format.leftmargin; format.link = fl, format.target = ft, format.image = fi; format.form = ff; format.js_event = js; } p->link_num++; last_link = stracpy(format.link); last_target = stracpy(format.target); last_image = stracpy(format.image); last_form = format.form; copy_js_event_spec(&last_js_event, format.js_event); if (!p->data) goto no_l; if (!(link = new_link(p->data))) goto no_l; link->num = p->link_num - 1; link->pos = DUMMY; copy_js_event_spec(&link->js_event, format.js_event); 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;/* SHADOWED IN g_html_form_control */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), d_opt); 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]), d_opt))) { 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, int marginwidth, int marginheight, unsigned char scrolling){ 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); fsd->f[fsd->xp + fsd->yp * fsd->x].marginwidth = marginwidth; fsd->f[fsd->xp + fsd->yp * fsd->x].marginheight = marginheight; fsd->f[fsd->xp + fsd->yp * fsd->x].scrolling = scrolling; 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_calloc(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, -1, -1, SCROLLING_AUTO); 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, fp->marginwidth, fp->marginheight, fp->scrolling);}void process_script(struct f_data *f, unsigned char *t){ if (t && !f->script_href_base) f->script_href_base = stracpy(format.href_base); if (!d_opt->js_enable) return; if (t) { unsigned char *u; u = join_urls(f->script_href_base, t); if (u) { request_additional_file(f, u); mem_free(u); } } f->are_there_scripts = 1;}void set_base(struct f_data *f, unsigned char *t){ if (!f->script_href_base) f->script_href_base = stracpy(format.href_base);}void html_process_refresh(struct f_data *f, unsigned char *url, int time){ if (!f) return; if (f->refresh) return; if (!url) f->refresh = stracpy(f->rq->url); else f->refresh = join_urls(f->rq->url, url); f->refresh_seconds = time;}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; struct refresh_param *rp; 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: return convert_table; case SP_USED: return (void *)(my_intptr_t)!!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; case SP_SCRIPT: t = va_arg(l, unsigned char *); va_end(l); if (p->data) process_script(p->data, t); break; case SP_REFRESH: rp = va_arg(l, struct refresh_param *);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -