Esempio n. 1
0
/** Checks cells left and right to the box for broken double-width chars.
 * Replace it with UCS_ORPHAN_CELL.
 *
 * @verbatim
 * 1+---+3
 * 1|box|##4
 * 1|   |##4
 * 1|   |##4
 * 1+---+##4
 *   2#####4
 * 1,2,3,4 - needs to be checked, # - shadow , +,-,| - border
 * @endverbatim
 */
void
fix_dwchar_around_box(struct terminal *term, struct box *box, int border,
		     int shadow_width, int shadow_height)
{
	struct screen_char *schar;
	int height, x, y;

	if (!term->utf8_cp)
		return;

	/* 1 */
	x = box->x - border - 1;
	if (x > 0) {
		y = box->y - border;
		height = box->height + 2 * border;

		schar = get_char(term, x, y);
		for (;height--; schar += term->width)
			if (unicode_to_cell(schar->data) == 2)
				schar->data = UCS_ORPHAN_CELL;
	}

	/* 2 */
	x = box->x - border + shadow_width - 1;
	if (x > 0 && x < term->width) {
		y = box->y + border + box->height;
		height = shadow_height;

		schar = get_char(term, x, y);
		for (;height--; schar += term->width)
			if (unicode_to_cell(schar->data) == 2)
				schar->data = UCS_ORPHAN_CELL;
	}

	/* 3 */
	x = box->x + box->width + border;
	if (x < term->width) {
		y = box->y - border;
		height = shadow_height;

		schar = get_char(term, x, y);
		for (;height--; schar += term->width)
			if (schar->data == UCS_NO_CHAR)
				schar->data = UCS_ORPHAN_CELL;
	}

	/* 4 */
	x = box->x + box->width + border + shadow_width;
	if (x < term->width) {
		y = box->y - border + shadow_height;
		height = box->height + 2 * border;

		schar = get_char(term, x, y);
		for (;height--; schar += term->width)
			if (schar->data == UCS_NO_CHAR)
				schar->data = UCS_ORPHAN_CELL;
	}
}
Esempio n. 2
0
draw_char_data(struct terminal *term, int x, int y, unsigned char data)
#endif /* CONFIG_UTF8 */
{
	struct screen_char *screen_char = get_char(term, x, y);

	if (!screen_char) return;

	screen_char->data = data;

#ifdef CONFIG_UTF8
#ifdef CONFIG_DEBUG
	/* Detect attempt to draw double-width char on the last
	 * column of terminal.  The unicode_to_cell(data) call is
	 * in principle wrong if CONFIG_UTF8 is defined but the
	 * charset of the terminal is not UTF-8, because @data
	 * is then a byte in that charset; but unicode_to_cell
	 * returns 1 for U+0000...U+00FF so it's not a problem.  */
	if (unicode_to_cell(data) == 2 && x + 1 > term->width)
		INTERNAL("Attempt to draw double-width glyph on last column!");
#endif /* CONFIG_DEBUG */

	if (data == UCS_NO_CHAR)
		screen_char->attr = 0;
#endif /* CONFIG_UTF8 */

	set_screen_dirty(term->screen, y, y);
}
Esempio n. 3
0
void
new_pos(struct form_state *fs, struct line_info *line, int current, int max_cells)
{
	unsigned char *text = fs->value + line[current].start;
	unsigned char *end = fs->value + line[current].end;
	int cells = 0;

	while(cells < max_cells) {
		unicode_val_T data = utf8_to_unicode(&text, end);

		if (data == UCS_NO_CHAR) break;
		cells += unicode_to_cell(data);
	}
	fs->state = (int)(text - fs->value);
}
Esempio n. 4
0
/*! Used by viewer to copy over a document.
 * When doing frame drawing @a x can be different than 0. */
void
draw_line(struct terminal *term, int x, int y, int l, struct screen_char *line)
{
	struct screen_char *screen_char = get_char(term, x, y);
	int size;

	assert(line);
	if_assert_failed return;
	if (!screen_char) return;

	size = int_min(l, term->width - x);
	if (size == 0) return;

#ifdef CONFIG_UTF8
	if (term->utf8_cp) {
		struct screen_char *sc;

		if (line[0].data == UCS_NO_CHAR && x == 0) {
			unicode_val_T data_save;

			sc = line;
			data_save = sc->data;
			sc->data = UCS_ORPHAN_CELL;
			copy_screen_chars(screen_char, line, 1);
			sc->data = data_save;
			size--;
			line++;
			screen_char++;

		}
		/* Instead of displaying double-width character at last column
		 * display only UCS_ORPHAN_CELL. */
		if (size - 1 > 0 && unicode_to_cell(line[size - 1].data) == 2) {
			unicode_val_T data_save;

			sc = &line[size - 1];
			data_save = sc->data;
			sc->data = UCS_ORPHAN_CELL;
			copy_screen_chars(screen_char, line, size);
			sc->data = data_save;
		} else {
			copy_screen_chars(screen_char, line, size);
		}
	} else
#endif
		copy_screen_chars(screen_char, line, size);
	set_screen_dirty(term->screen, y, y);
}
Esempio n. 5
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);

}
Esempio n. 6
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);
}