void draw_textarea(struct terminal *term, struct form_state *fs, struct document_view *doc_view, struct link *link) { struct line_info *line, *linex; struct form_control *fc; struct box *box; int vx, vy; int sl, ye; int x, y; assert(term && doc_view && doc_view->document && doc_view->vs && link); if_assert_failed return; #ifdef CONFIG_UTF8 if (term->utf8_cp) { draw_textarea_utf8(term, fs, doc_view, link); return; } #endif /* CONFIG_UTF8 */ fc = get_link_form_control(link); assertm(fc != NULL, "link %d has no form control", (int) (link - doc_view->document->links)); if_assert_failed return; box = &doc_view->box; vx = doc_view->vs->x; vy = doc_view->vs->y; if (!link->npoints) return; #ifdef CONFIG_UTF8 area_cursor(fc, fs, 0); #else area_cursor(fc, fs); #endif /* CONFIG_UTF8 */ linex = format_text(fs->value, fc->cols, fc->wrap, 0); if (!linex) return; line = linex; sl = fs->vypos; while (line->start != -1 && sl) sl--, line++; x = link->points[0].x + box->x - vx; y = link->points[0].y + box->y - vy; ye = y + fc->rows; for (; line->start != -1 && y < ye; line++, y++) { int i; if (!row_is_in_box(box, y)) continue; for (i = 0; i < fc->cols; i++) { unsigned char data; int xi = x + i; if (!col_is_in_box(box, xi)) continue; if (i >= -fs->vpos && i + fs->vpos < line->end - line->start) data = fs->value[line->start + i + fs->vpos]; else data = '_'; draw_char_data(term, xi, y, data); } } for (; y < ye; y++) { int i; if (!row_is_in_box(box, y)) continue; for (i = 0; i < fc->cols; i++) { int xi = x + i; if (col_is_in_box(box, xi)) draw_char_data(term, xi, y, '_'); } } mem_free(linex); }
static void draw_text_utf8(struct terminal *term, int x, int y, const unsigned char *text, int length, int attr, struct color_pair *color) { struct screen_char *start, *pos; unsigned char *end = text + length; unicode_val_T data; assert(text && length >= 0); if_assert_failed return; if (length <= 0) return; if (x >= term->width) return; data = utf8_to_unicode(&text, end); if (data == UCS_NO_CHAR) return; start = get_char(term, x, y); if (color) { start->attr = attr; set_term_color(start, color, 0, get_opt_int_tree(term->spec, (const unsigned char *)"colors", NULL)); } if (start->data == UCS_NO_CHAR && x - 1 > 0) draw_char_data(term, x - 1, y, UCS_ORPHAN_CELL); pos = start; if (unicode_to_cell(data) == 2) { /* Is there enough room for whole double-width char? */ if (x + 1 < term->width) { pos->data = data; pos++; x++; pos->data = UCS_NO_CHAR; pos->attr = 0; } else { pos->data = UCS_ORPHAN_CELL; } } else { pos->data = data; } pos++; x++; for (; x < term->width; x++, pos++) { data = utf8_to_unicode(&text, end); if (data == UCS_NO_CHAR) break; if (color) copy_screen_chars(pos, start, 1); if (unicode_to_cell(data) == 2) { /* Is there enough room for whole double-width char? */ if (x + 1 < term->width) { pos->data = data; x++; pos++; pos->data = UCS_NO_CHAR; pos->attr = 0; } else { pos->data = UCS_ORPHAN_CELL; } } else { pos->data = data; } } set_screen_dirty(term->screen, y, y); }
static void draw_textarea_utf8(struct terminal *term, struct form_state *fs, struct document_view *doc_view, struct link *link) { struct line_info *line, *linex; struct form_control *fc; struct box *box; int vx, vy; int sl, ye; int x, xbase, y; assert(term && doc_view && doc_view->document && doc_view->vs && link); if_assert_failed return; fc = get_link_form_control(link); assertm(fc != NULL, "link %d has no form control", (int) (link - doc_view->document->links)); if_assert_failed return; box = &doc_view->box; vx = doc_view->vs->x; vy = doc_view->vs->y; if (!link->npoints) return; area_cursor(fc, fs, 1); linex = format_textutf8(fs->value, fc->cols, fc->wrap, 0); if (!linex) return; line = linex; sl = fs->vypos; while (line->start != -1 && sl) sl--, line++; xbase = link->points[0].x + box->x - vx; y = link->points[0].y + box->y - vy; ye = y + fc->rows; for (; line->start != -1 && y < ye; line++, y++) { int i; unsigned char *text, *end; text = fs->value + line->start; end = fs->value + line->end; text += utf8_cells2bytes(text, fs->vpos, end); if (!row_is_in_box(box, y)) continue; for (i = 0, x = xbase; i < fc->cols; i++, x++) { unicode_val_T data; if (i >= -fs->vpos && text < end) { /* utf8_to_unicode will increment text. */ data = utf8_to_unicode(&text, end); } else data = '_'; if (col_is_in_box(box, x)) { int cell = unicode_to_cell(data); if (cell == 2) { draw_char_data(term, x++, y, data); i++; data = UCS_NO_CHAR; } draw_char_data(term, x, y, data); } } } for (; y < ye; y++) { int i; if (!row_is_in_box(box, y)) continue; for (i = 0, x = xbase; i < fc->cols; i++, x++) { if (col_is_in_box(box, x)) draw_char_data(term, x, y, '_'); } } mem_free(linex); }