📄 html_gr.c
字号:
void g_put_chars(struct g_part *p, unsigned char *s, int l){ struct g_object_text *t = NULL; struct link *link; if (putchars_link_ptr) { link = NULL; goto check_link; } while (par_format.align != AL_NO && p->cx == -1 && l && *s == ' ') s++, l--; if (!l) return; g_nobreak = 0; if (p->cx < par_format.leftmargin * G_HTML_MARGIN) p->cx = par_format.leftmargin * G_HTML_MARGIN; if (html_format_changed) { if (memcmp(&ta_cache, &format, sizeof(struct text_attrib_beginning)) || xstrcmp(cached_font_face, format.fontface) || cached_font_face == to_je_ale_prasarna || 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 (!html_format_changed) internal("html_format_changed not set");*/ flush_pending_text_to_line(p); if (xstrcmp(cached_font_face, format.fontface) || cached_font_face == to_je_ale_prasarna) { if (cached_font_face && cached_font_face != to_je_ale_prasarna) mem_free(cached_font_face); cached_font_face = stracpy(format.fontface); } memcpy(&ta_cache, &format, sizeof(struct text_attrib_beginning)); if (p->current_style) g_free_style(p->current_style); p->current_style = get_style_by_ta(&format); } html_format_changed = 0; } /*if (p->cx <= par_format.leftmargin * G_HTML_MARGIN && *s == ' ' && par_format.align != AL_NO) s++, l--;*/ if (!p->text) { link = NULL; t = mem_calloc(sizeof(struct g_object_text) + ALLOC_GR); t->mouse_event = g_text_mouse; t->draw = g_text_draw; t->destruct = g_text_destruct; t->get_list = NULL; /*t->style = get_style_by_ta(format);*/ t->style = g_clone_style(p->current_style); t->bg = NULL; /* FIXME!!! */ t->yw = t->style->height; /*t->xw = 0; t->y = 0;*/ if (format.baseline) { if (format.baseline < 0) t->y = -(t->style->height / 3); if (format.baseline > 0) t->y = get_real_font_size(format.baseline) - (t->style->height / 2); } check_link: if (last_link || last_image || last_form || format.link || format.image || format.form || format.js_event || last_js_event ) goto process_link; back_link: if (putchars_link_ptr) { *putchars_link_ptr = link; return; } if (!link) t->link_num = -1; else { t->link_num = link - p->data->links; t->link_order = link->obj_order++; } t->text[0] = 0; p->pending_text_len = 0; p->text = t; } if (p->pending_text_len == -1) { p->pending_text_len = strlen(p->text->text); goto a1; } if ((p->pending_text_len & ~(ALLOC_GR - 1)) != ((p->pending_text_len + l) & ~(ALLOC_GR - 1))) a1:{ struct g_object_text *t; if ((unsigned)l > MAXINT) overalloc(); if ((unsigned)p->pending_text_len + (unsigned)l > MAXINT - ALLOC_GR) overalloc(); t = mem_realloc(p->text, sizeof(struct g_object_text) + ((p->pending_text_len + l + ALLOC_GR) & ~(ALLOC_GR - 1))); if (p->w.last_wrap >= p->text->text && p->w.last_wrap < p->text->text + p->pending_text_len) p->w.last_wrap += (unsigned char *)t - (unsigned char *)p->text; if (p->w.last_wrap_obj == p->text) p->w.last_wrap_obj = t; p->text = t; } memcpy(p->text->text + p->pending_text_len, s, l), p->text->text[p->pending_text_len += l] = 0; p->text->xw += g_text_width(p->text->style, p->text->text + p->pending_text_len - l); /* !!! FIXME: move to g_wrap_text */ if (par_format.align != AL_NO) { p->w.text = p->text->text + p->pending_text_len - l; p->w.style = p->text->style; p->w.obj = p->text; p->w.width = rm(par_format) - par_format.leftmargin * G_HTML_MARGIN; if (p->w.width < 0) p->w.width = 0; if (!g_wrap_text(&p->w)) { split_line_object(p, p->w.last_wrap_obj, p->w.last_wrap); } } return; /* !!! WARNING: THE FOLLOWING CODE IS SHADOWED IN HTML_R.C */ process_link: if ((last_link /*|| last_target*/ || last_image || last_form) && !putchars_link_ptr && !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 back_link; if (!p->data->nlinks) { internal("no link"); goto back_link; } link = &p->data->links[p->data->nlinks - 1]; goto back_link; } 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 back_link; /*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; struct js_event_spec *js = format.js_event; format.link = format.target = format.image = NULL; format.form = NULL; format.js_event = NULL; s[0] = '['; snzprint(s + 1, 62, p->link_num); strcat(s, "]"); g_put_chars(p, s, strlen(s)); if (ff && ff->type == FC_TEXTAREA) g_line_break(p); if (p->cx < par_format.leftmargin * G_HTML_MARGIN) p->cx = par_format.leftmargin * G_HTML_MARGIN; 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 back_link; if (!(link = new_link(p->data))) goto back_link; 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); link->sel_color = 0; link->n = 0; } goto back_link;}void g_do_format(char *start, char *end, struct g_part *part, unsigned char *head){ pr( parse_html(start, end, (int (*)(void *, unsigned char *, int)) g_put_chars_conv, (void (*)(void *)) g_line_break, (void *(*)(void *, int, ...)) g_html_special, part, head); /*if ((part->y -= line_breax) < 0) part->y = 0;*/ flush_pending_text_to_line(part); flush_pending_line_to_obj(part, 0); ) {};}struct g_table_cache_entry { struct g_table_cache_entry *next; struct g_table_cache_entry *prev; unsigned char *start; unsigned char *end; int align; int m; int width; int link_num; struct g_part p;};struct list_head g_table_cache = { &g_table_cache, &g_table_cache };void g_free_table_cache(void){ free_list(g_table_cache);}struct g_part *g_format_html_part(unsigned char *start, unsigned char *end, int align, int m, int width, unsigned char *head, int link_num, unsigned char *bg, unsigned char *bgcolor, struct f_data *f_d){ int wa; struct g_part *p; struct html_element *e; struct form_control *fc; int lm = margin; struct g_table_cache_entry *tce; if (!f_d) foreach(tce, g_table_cache) { if (tce->start == start && tce->end == end && tce->align == align && tce->m == m && tce->width == width && tce->link_num == link_num) { p = mem_alloc(sizeof(struct g_part)); memcpy(p, &tce->p, sizeof(struct part)); return p; } } margin = m; /*d_opt->tables = 0;*/ 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; cached_font_face = to_je_ale_prasarna; p = mem_calloc(sizeof(struct g_part)); { struct g_object_area *a; a = mem_calloc(sizeof(struct g_object_area) + sizeof(struct g_object_line *)); a->bg = get_background(bg, bgcolor); if (bgcolor) decode_color(bgcolor, &format.bg); if (bgcolor) decode_color(bgcolor, &par_format.bgcolor); a->mouse_event = g_area_mouse; a->draw = g_area_draw; a->destruct = g_area_destruct; a->get_list = g_area_get_list; a->lfo = DUMMY; a->rfo = DUMMY; a->n_lines = 0; p->root = a; init_list(p->uf); } p->data = f_d; p->x = p->y = 0; p->xmax = 0; 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; g_nobreak = 1; g_do_format(start, end, p, head); g_nobreak = 0; line_breax = 1; 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; wa = g_get_area_width(p->root); if (wa > p->x) p->x = wa; g_x_extend_area(p->root, p->x, 0); if (p->x > p->xmax) p->xmax = p->x; p->y = p->root->yw; /*debug("WIDTH: obj (%d, %d), p (%d %d)", p->root->xw, p->root->yw, p->x, p->y);*/ kill_html_stack_item(&html_top); if (!f_d) g_release_part(p), p->root = NULL; if (cached_font_face && cached_font_face != to_je_ale_prasarna) mem_free(cached_font_face); cached_font_face = to_je_ale_prasarna; foreach(fc, p->uf) destroy_fc(fc); free_list(p->uf); margin = lm; 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; if (table_level > 1 && !f_d) { tce = mem_alloc(sizeof(struct g_table_cache_entry)); tce->start = start; tce->end = end; tce->align = align; tce->m = m; tce->width = width; tce->link_num = link_num; memcpy(&tce->p, p, sizeof(struct g_part)); add_to_list(g_table_cache, tce); } return p;}void g_release_part(struct g_part *p){ if (p->text) p->text->destruct(p->text); if (p->line) p->line->destruct(p->line); if (p->root) p->root->destruct(p->root); if (p->current_style) g_free_style(p->current_style);}void g_scan_width(struct g_object **o, int n, int *w){ while (n--) { if ((*o)->x + (*o)->xw > *w) *w = (*o)->x + (*o)->xw; o++; }}void g_scan_lines(struct g_object_line **o, int n, int *w){ while (n--) { if ((*o)->n_entries) { struct g_object *oo = (*o)->entries[(*o)->n_entries - 1]; if ((*o)->x + oo->x + oo->xw > *w) *w = (*o)->x + oo->x + oo->xw; } o++; }}int g_get_area_width(struct g_object_area *a){ int w = 0; g_scan_width(a->lfo, a->n_lfo, &w); g_scan_width(a->rfo, a->n_rfo, &w); g_scan_lines(a->lines, a->n_lines, &w); return w;}void g_x_extend_area(struct g_object_area *a, int width, int height){ struct g_object_line *l; int i; a->xw = width; for (i = 0; i < a->n_lines; i++) { a->lines[i]->xw = width; } for (i = a->n_lines - 1; i >= 0; i--) { l = a->lines[i]; if (!l->n_entries) { a->yw -= l->yw; l->destruct(l); a->n_lines--; continue; } break; } if (a->yw >= height) return; l = mem_calloc(sizeof(struct g_object_line)); l->mouse_event = g_line_mouse; l->draw = g_line_draw; l->destruct = g_line_destruct; l->get_list = g_line_get_list; l->x = 0; l->y = a->yw; l->xw = width; l->yw = height - a->yw; l->bg = a->bg; l->n_entries = 0; a->lines[a->n_lines] = l; a->n_lines++;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -