Example #1
0
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);
}
Example #2
0
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);

}
Example #3
0
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);
}