示例#1
0
static int
read_row(char *source, NCURSES_CH_T * prior, NCURSES_CH_T * target, int length)
{
    while (*source != '\0' && length > 0) {
#if NCURSES_WIDECHAR
	int n, len;
	source = decode_cchar(source, prior, target);
	len = wcwidth(target->chars[0]);
	if (len > 1) {
	    SetWidecExt(CHDEREF(target), 0);
	    for (n = 1; n < len; ++n) {
		target[n] = target[0];
		SetWidecExt(CHDEREF(target), n);
	    }
	    target += (len - 1);
	    length -= (len - 1);
	}
#else
	source = decode_chtype(source, *prior, target);
#endif
	*prior = *target;
	++target;
	--length;
    }
    while (length-- > 0) {
	*target++ = blank;
    }
    /* FIXME - see what error conditions should apply if I need to return ERR */
    return 0;
}
示例#2
0
_nc_insert_wch(WINDOW *win, const cchar_t *wch)
{
    int cells = wcwidth(CharOf(CHDEREF(wch)));
    int cell;
    int code = OK;

    if (cells < 0) {
	code = winsch(win, (chtype) CharOf(CHDEREF(wch)));
    } else {
	if (cells == 0)
	    cells = 1;

	if (win->_curx <= win->_maxx) {
	    struct ldat *line = &(win->_line[win->_cury]);
	    NCURSES_CH_T *end = &(line->text[win->_curx]);
	    NCURSES_CH_T *temp1 = &(line->text[win->_maxx]);
	    NCURSES_CH_T *temp2 = temp1 - cells;

	    CHANGED_TO_EOL(line, win->_curx, win->_maxx);
	    while (temp1 > end)
		*temp1-- = *temp2--;

	    *temp1 = _nc_render(win, *wch);
	    for (cell = 1; cell < cells; ++cell) {
		SetWidecExt(temp1[cell], cell);
	    }

	    win->_curx = (NCURSES_SIZE_T) (win->_curx + cells);
	}
    }
    return code;
}
示例#3
0
/*
 * Insert the given character, updating the current location to simplify
 * inserting a string.
 */
static int
_nc_insert_wch(WINDOW *win, const cchar_t *wch)
{
    int cells = wcwidth(CharOf(CHDEREF(wch)));
    int cell;

    if (cells <= 0)
        cells = 1;

    if (win->_curx <= win->_maxx) {
        struct ldat *line = &(win->_line[win->_cury]);
        NCURSES_CH_T *end = &(line->text[win->_curx]);
        NCURSES_CH_T *temp1 = &(line->text[win->_maxx]);
        NCURSES_CH_T *temp2 = temp1 - cells;

        CHANGED_TO_EOL(line, win->_curx, win->_maxx);
        while (temp1 > end)
            *temp1-- = *temp2--;

        *temp1 = _nc_render(win, *wch);
        for (cell = 1; cell < cells; ++cell) {
            SetWidecExt(temp1[cell], cell);
        }

        win->_curx++;
    }
    return OK;
}
static int
wadd_wch_literal(WINDOW *win, cchar_t ch)
{
    int x;
    int y;
    struct ldat *line;

    x = win->_curx;
    y = win->_cury;

    CHECK_POSITION(win, x, y);

    ch = render_char(win, ch);

    line = win->_line + y;

    CHANGED_CELL(line, x);

    /*
     * Non-spacing characters are added to the current cell.
     *
     * Spacing characters that are wider than one column require some display
     * adjustments.
     */
    {
	int len = wcwidth(CharOf(ch));
	int i;
	int j;
	wchar_t *chars;

	if (len == 0) {		/* non-spacing */
	    if ((x > 0 && y >= 0)
		|| (win->_maxx >= 0 && win->_cury >= 1)) {
		if (x > 0 && y >= 0)
		    chars = (win->_line[y].text[x - 1].chars);
		else
		    chars = (win->_line[y - 1].text[win->_maxx].chars);
		for (i = 0; i < CCHARW_MAX; ++i) {
		    if (chars[i] == 0) {
			TR(TRACE_VIRTPUT,
			   ("added non-spacing %d: %x",
			    x, (int) CharOf(ch)));
			chars[i] = CharOf(ch);
			break;
		    }
		}
	    }
	    goto testwrapping;
	} else if (len > 1) {	/* multi-column characters */
	    /*
	     * Check if the character will fit on the current line.  If it does
	     * not fit, fill in the remainder of the line with blanks.  and
	     * move to the next line.
	     */
	    if (len > win->_maxx + 1) {
		TR(TRACE_VIRTPUT, ("character will not fit"));
		return ERR;
	    } else if (x + len > win->_maxx + 1) {
		int count = win->_maxx + 1 - x;
		TR(TRACE_VIRTPUT, ("fill %d remaining cells", count));
		fill_cells(win, count);
		if (wrap_to_next_line(win) == ERR)
		    return ERR;
		x = win->_curx;
		y = win->_cury;
		line = win->_line + y;
	    }
	    /*
	     * Check for cells which are orphaned by adding this character, set
	     * those to blanks.
	     *
	     * FIXME: this actually could fill j-i cells, more complicated to
	     * setup though.
	     */
	    for (i = 0; i < len; ++i) {
		if (isWidecBase(win->_line[y].text[x + i])) {
		    break;
		} else if (isWidecExt(win->_line[y].text[x + i])) {
		    for (j = i; x + j <= win->_maxx; ++j) {
			if (!isWidecExt(win->_line[y].text[x + j])) {
			    TR(TRACE_VIRTPUT, ("fill %d orphan cells", j));
			    fill_cells(win, j);
			    break;
			}
		    }
		    break;
		}
	    }
	    /*
	     * Finally, add the cells for this character.
	     */
	    for (i = 0; i < len; ++i) {
		cchar_t value = ch;
		SetWidecExt(value, i);
		TR(TRACE_VIRTPUT, ("multicolumn %d:%d (%d,%d)",
				   i + 1, len,
				   win->_begy + y, win->_begx + x));
		line->text[x] = value;
		CHANGED_CELL(line, x);
		++x;
	    }
	    goto testwrapping;
	}
    }

    /*
     * Single-column characters.
     */
    line->text[x++] = ch;
    /*
     * This label is used only for wide-characters.
     */
  testwrapping:

    TR(TRACE_VIRTPUT, ("cell (%ld, %ld..%d) = %s",
		       (long) win->_cury, (long) win->_curx, x - 1,
		       _tracech_t(CHREF(ch))));

    if (x > win->_maxx) {
	return wrap_to_next_line(win);
    }
    win->_curx = (NCURSES_SIZE_T) x;
    return OK;
}
示例#5
0
wadd_wchnstr(WINDOW *win, const cchar_t *astr, int n)
{
    NCURSES_CH_T blank = NewChar(BLANK_TEXT);
    NCURSES_SIZE_T y = win->_cury;
    NCURSES_SIZE_T x = win->_curx;
    int code = OK;
    struct ldat *line;
    int i, j, start, len, end;

    T((T_CALLED("wadd_wchnstr(%p,%s,%d)"), win, _nc_viscbuf(astr, n), n));

    if (!win)
	returnCode(ERR);

    if (n < 0) {
	n = _nc_wchstrlen(astr);
    }
    if (n > win->_maxx - x + 1)
	n = win->_maxx - x + 1;
    if (n == 0)
	returnCode(code);

    line = &(win->_line[y]);
    start = x;
    end = x + n - 1;

    /*
     * Reset orphaned cells of multi-column characters that extend up to the
     * new string's location to blanks.
     */
    if (x > 0 && isWidecExt(line->text[x])) {
	for (i = 0; i <= x; ++i) {
	    if (!isWidecExt(line->text[x - i])) {
		/* must be isWidecBase() */
		start -= i;
		while (i > 0) {
		    line->text[x - i--] = _nc_render(win, blank);
		}
		break;
	    }
	}
    }

    /*
     * Copy the new string to the window.
     */
    for (i = 0; i < n && x <= win->_maxx; ++i) {
	if (isWidecExt(astr[i]))
	    continue;

	len = wcwidth(CharOf(astr[i]));

	if (x + len - 1 <= win->_maxx) {
	    line->text[x] = _nc_render(win, astr[i]);
	    if (len > 1) {
		for (j = 0; j < len; ++j) {
		    if (j != 0) {
			line->text[x + j] = line->text[x];
		    }
		    SetWidecExt(line->text[x + j], j);
		}
	    }
	    x += len;
	    end += len - 1;
	} else {
	    break;
	}
    }

    /*
     * Set orphaned cells of multi-column characters which lie after the new
     * string to blanks.
     */
    while (x <= win->_maxx && isWidecExt(line->text[x])) {
	line->text[x] = _nc_render(win, blank);
	++end;
	++x;
    }
    CHANGED_RANGE(line, start, end);

    _nc_synchook(win);
    returnCode(code);
}