⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 redraw.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* redraw.c *//* Author: *	Steve Kirkendall *	14407 SW Teal Blvd. #C *	Beaverton, OR 97005 *	kirkenda@cs.pdx.edu *//* This file contains functions that draw text on the screen.  The major entry * points are: *	redrawrange()	- called from modify.c to give hints about what parts *			  of the screen need to be redrawn. *	redraw()	- redraws the screen (or part of it) and positions *			  the cursor where it belongs. *	idx2col()	- converts a markidx() value to a logical column number. */#include "config.h"#include "vi.h"/* This variable contains the line number that smartdrawtext() knows best */static long smartlno;/* This function remembers where changes were made, so that the screen can be * redraw in a more efficient manner. */static long	redrawafter;	/* line# of first line that must be redrawn */static long	preredraw;	/* line# of last line changed, before change */static long	postredraw;	/* line# of last line changed, after change */static int	mustredraw;	/* boolean: anything forcing a screen update? */void redrawrange(after, pre, post)	long	after;	/* lower bound of redrawafter */	long	pre;	/* upper bound of preredraw */	long	post;	/* upper bound of postredraw */{	if (after == redrawafter)	{		/* multiple insertions/deletions at the same place -- combine		 * them		 */		preredraw -= (post - pre);		if (postredraw < post)		{			preredraw += (post - postredraw);			postredraw = post;		}		if (redrawafter > preredraw)		{			redrawafter = preredraw;		}		if (redrawafter < 1L)		{			redrawafter = 0L;			preredraw = postredraw = INFINITY;		}	}	else if (postredraw > 0L)	{		/* multiple changes in different places -- redraw everything		 * after "after".		 */		postredraw = preredraw = INFINITY;		if (after < redrawafter)			redrawafter = after;	}	else	{		/* first change */		redrawafter = after;		preredraw = pre;		postredraw = post;	}	mustredraw = TRUE;}#ifndef NO_CHARATTR/* see if a given line uses character attribute strings */static int hasattr(lno, text)	long		lno;	/* the line# of the cursor */	REG char	*text;	/* the text of the line, from fetchline */{	static long	plno;	/* previous line number */	static long	chgs;	/* previous value of changes counter */	static int	panswer;/* previous answer */	char		*scan;	/* if charattr is off, then the answer is "no, it doesn't" */	if (!*o_charattr)	{		chgs = 0; /* <- forces us to check if charattr is later set */		return FALSE;	}	/* if we already know the answer, return it... */	if (lno == plno && chgs == changes)	{		return panswer;	}	/* get the line & look for "\fX" */	if (!text[0] || !text[1] || !text[2])	{		panswer = FALSE;	}	else	{		for (scan = text; scan[2] && !(scan[0] == '\\' && scan[1] == 'f'); scan++)		{		}		panswer = (scan[2] != '\0');	}	/* save the results */	plno = lno;	chgs = changes;	/* return the results */	return panswer;}#endif#ifndef NO_VISIBLE/* This function checks to make sure that the correct lines are shown in * reverse-video.  This is used to handle the "v" and "V" commands. */static long	vizlow, vizhigh;	/* the starting and ending lines */static int	vizleft, vizright;	/* starting & ending indicies */static int	vizchange;		/* boolean: must use stupid drawtext? */static void setviz(curs)	MARK		curs;{	long		newlow, newhigh;	long		extra = 0L;	/* for now, assume the worst... */	vizchange = TRUE;	/* set newlow & newhigh according to V_from and cursor */	if (!V_from)	{		/* no lines should have reverse-video */		if (vizlow)		{			redrawrange(vizlow, vizhigh + 1L, vizhigh + 1L);			vizlow = vizhigh = 0L;		}		else		{			vizchange = FALSE;		}		return;	}	/* figure out which lines *SHOULD* have hilites */	if (V_from < curs)	{		newlow = markline(V_from);		newhigh = markline(curs);		vizleft = markidx(V_from);		vizright = markidx(curs) + 1;	}	else	{		newlow = markline(curs);		newhigh = markline(V_from);		vizleft = markidx(curs);		vizright = markidx(V_from) + 1;	}	/* adjust for line-mode hiliting */	if (V_linemd)	{		vizleft = 0;		vizright = BLKSIZE - 1;	}	else	{		extra = 1L;	}	/* arrange for the necessary lines to be redrawn */	if (vizlow == 0L)	{		/* just starting to redraw */		redrawrange(newlow, newhigh, newhigh);	}	else	{		/* Were new lines added/removed at the front? */		if (newlow != vizlow)		{			if (newlow < vizlow)				redrawrange(newlow, vizlow + extra, vizlow + extra);			else				redrawrange(vizlow, newlow + extra, newlow + extra);		}		/* Were new lines added/removed at the back? */		if (newhigh != vizhigh)		{			if (newhigh < vizhigh)				redrawrange(newhigh + 1L - extra, vizhigh + 1L, vizhigh + 1L);			else				redrawrange(vizhigh + 1L - extra, newhigh, newhigh);		}	}	/* remember which lines will contain hilighted text now */	vizlow = newlow;	vizhigh = newhigh;}#endif /* !NO_VISIBLE *//* This function converts a MARK to a column number.  It doesn't automatically * adjust for leftcol; that must be done by the calling function */int idx2col(curs, text, inputting)	MARK		curs;	/* the line# & index# of the cursor */	REG char	*text;	/* the text of the line, from fetchline */	int		inputting;	/* boolean: called from input() ? */{	static MARK	pcursor;/* previous cursor, for possible shortcut */	static MARK	pcol;	/* column number for pcol */	static long	chgs;	/* previous value of changes counter */	REG int		col;	/* used to count column numbers */	REG int		idx;	/* used to count down the index */	REG int		i;	/* for now, assume we have to start counting at the left edge */	col = 0;	idx = markidx(curs);	/* if the file hasn't changed & line number is the same & it has no	 * embedded character attribute strings, can we do shortcuts?	 */	if (chgs == changes	 && !((curs ^ pcursor) & ~(BLKSIZE - 1))#ifndef NO_CHARATTR	 && !hasattr(markline(curs), text)#endif	)	{		/* no movement? */		if (curs == pcursor)		{			/* return the column of the char; for tabs, return its last column */			if (text[idx] == '\t' && !inputting && !*o_list)			{				return pcol + *o_tabstop - (pcol % *o_tabstop) - 1;			}			else			{				return pcol;			}		}		/* movement to right? */		if (curs > pcursor)		{			/* start counting from previous place */			col = pcol;			idx = markidx(curs) - markidx(pcursor);			text += markidx(pcursor);		}	}	/* count over to the char after the idx position */	while (idx > 0 && (i = *text)) /* yes, ASSIGNMENT! */	{		if (i == '\t' && !*o_list)		{			col += *o_tabstop;			col -= col % *o_tabstop;		}		else if (i >= '\0' && i < ' ' || i == '\177')		{			col += 2;		}#ifndef NO_CHARATTR		else if (i == '\\' && text[1] == 'f' && text[2] && *o_charattr)		{			text += 2; /* plus one more at bottom of loop */			idx -= 2;		}			#endif		else		{			col++;		}		text++;		idx--;	}	/* save stuff to speed next call */	pcursor = curs;	pcol = col;	chgs = changes;	/* return the column of the char; for tabs, return its last column */	if (*text == '\t' && !inputting && !*o_list)	{		return col + *o_tabstop - (col % *o_tabstop) - 1;	}	else	{		return col;	}}/* This function is similar to idx2col except that it takes care of sideways * scrolling - for the given line, at least. */int mark2phys(m, text, inputting)	MARK	m;		/* a mark to convert */	char	*text;		/* the line that m refers to */	int	inputting;	/* boolean: caled from input() ? */{	int	i;	i = idx2col(m, text, inputting);	while (i < leftcol)	{		leftcol -= *o_sidescroll;		mustredraw = TRUE;		redrawrange(1L, INFINITY, INFINITY);	}	while (i > rightcol)	{		leftcol += *o_sidescroll;		mustredraw = TRUE;		redrawrange(1L, INFINITY, INFINITY);	}	physrow = markline(m) - topline;	physcol = i - leftcol;	if (*o_number)		physcol += 8;	return physcol;}/* This function draws a single line of text on the screen.  The screen's * cursor is assumed to be located at the leftmost column of the appropriate * row. */static void drawtext(text, lno, clr)	REG char	*text;	/* the text to draw */	long		lno;	/* the number of the line to draw */	int		clr;	/* boolean: do a clrtoeol? */{	REG int		col;	/* column number */	REG int		i;	REG int		tabstop;	/* *o_tabstop */	REG int		limitcol;	/* leftcol or leftcol + COLS */	int		abnormal;	/* boolean: charattr != A_NORMAL? */#ifndef NO_VISIBLE	int		rev;		/* boolean: standout mode, too? */	int		idx = 0;#endif	char		numstr[9];	/* show the line number, if necessary */	if (*o_number)	{		sprintf(numstr, "%6ld |", lno);		qaddstr(numstr);	}#ifndef NO_SENTENCE	/* if we're hiding format lines, and this is one of them, then hide it */	if (*o_hideformat && *text == '.')	{		clrtoeol();#if OSK		qaddch('\l');#else		qaddch('\n');#endif		return;	}#endif	/* move some things into registers... */	limitcol = leftcol;	tabstop = *o_tabstop;	abnormal = FALSE;#ifndef CRUNCH	if (clr)		clrtoeol();#endif	/* skip stuff that was scrolled off left edge */	for (col = 0;	     (i = *text) && col < limitcol; /* yes, ASSIGNMENT! */	     text++)	{#ifndef NO_VISIBLE		idx++;#endif		if (i == '\t' && !*o_list)		{			col = col + tabstop - (col % tabstop);		}		else if (i >= 0 && i < ' ' || i == '\177')		{			col += 2;		}#ifndef NO_CHARATTR		else if (i == '\\' && text[1] == 'f' && text[2] && *o_charattr)		{			text += 2; /* plus one more as part of "for" loop */			/* since this attribute might carry over, we need it */			switch (*text)			{			  case 'R':			  case 'P':				attrset(A_NORMAL);				abnormal = FALSE;				break;			  case 'B':				attrset(A_BOLD);				abnormal = TRUE;				break;			  case 'U':				attrset(A_UNDERLINE);				abnormal = TRUE;				break;			  case 'I':				attrset(A_ALTCHARSET);				abnormal = TRUE;				break;			}		}#endif		else		{			col++;		}	}#ifndef NO_VISIBLE	/* Should we start hiliting at the first char of this line? */	if ((lno > vizlow && lno <= vizhigh	    || lno == vizlow && vizleft < idx)	   && !(lno == vizhigh && vizright < idx))	{		do_VISIBLE();		rev = TRUE;	}#endif	/* adjust for control char that was partially visible */	while (col > limitcol)	{		qaddch(' ');		limitcol++;	}	/* now for the visible characters */	limitcol = leftcol + COLS;	if (*o_number)		limitcol -= 8;	for (; (i = *text) && col < limitcol; text++)	{#ifndef NO_VISIBLE		/* maybe turn hilite on/off in the middle of the line */		if (lno == vizlow && vizleft == idx)		{			do_VISIBLE();			rev = TRUE;		}		if (lno == vizhigh && vizright == idx)		{			do_SE();			rev = FALSE;		}		idx++;		/* if hiliting, never emit physical tabs */		if (rev && i == '\t' && !*o_list)		{			i = col + tabstop - (col % tabstop);			do			{				qaddch(' ');				col++;			} while (col < i);		}		else#endif /* !NO_VISIBLE */		if (i == '\t' && !*o_list)		{			i = col + tabstop - (col % tabstop);			if (i < limitcol)			{#ifdef CRUNCH				if (!clr && has_PT && !((i - leftcol) & 7))#else				if (has_PT && !((i - leftcol) & 7))#endif				{					do					{						qaddch('\t');						col += 8; /* not exact! */					} while (col < i);					col = i; /* NOW it is exact */				}				else				{					do					{						qaddch(' ');						col++;					} while (col < i);				}			}			else /* tab ending after screen? next line! */			{				col = limitcol;				if (has_AM)				{					addch('\n');	/* GB */				}			}		}		else if (i >= 0 && i < ' ' || i == '\177')		{			col += 2;			qaddch('^');			if (col <= limitcol)			{				qaddch(i ^ '@');			}		}#ifndef NO_CHARATTR		else if (i == '\\' && text[1] == 'f' && text[2] && *o_charattr)		{			text += 2; /* plus one more as part of "for" loop */			switch (*text)			{			  case 'R':			  case 'P':				attrset(A_NORMAL);				abnormal = FALSE;				break;			  case 'B':				attrset(A_BOLD);				abnormal = TRUE;				break;			  case 'U':				attrset(A_UNDERLINE);				abnormal = TRUE;				break;			  case 'I':				attrset(A_ALTCHARSET);				abnormal = TRUE;				break;			}		}#endif		else		{			col++;			qaddch(i);		}	}	/* get ready for the next line */#ifndef NO_CHARATTR	if (abnormal)	{		attrset(A_NORMAL);	}#endif	if (*o_list && col < limitcol)	{		qaddch('$');		col++;	}#ifndef NO_VISIBLE	/* did we hilite this whole line?  If so, STOP! */	if (rev)	{		do_SE();	}#endif#ifdef CRUNCH	if (clr && col < limitcol)	{		clrtoeol();	}#endif	if (!has_AM || col < limitcol)	{		addch('\n');	}	wqrefresh();}#ifndef CRUNCHstatic void nudgecursor(same, scan, new, lno)	int	same;	/* number of chars to be skipped over */	char	*scan;	/* where the same chars end */	char	*new;	/* where the visible part of the line starts */	long	lno;	/* line number of this line */{	int	col;	if (same > 0)	{		if (same < 5)		{			/* move the cursor by overwriting */			while (same > 0)			{				qaddch(scan[-same]);				same--;			}		}		else		{			/* move the cursor by calling move() */			col = (int)(scan - new);			if (*o_number)				col += 8;			move((int)(lno - topline), col);		}	}}#endif /* not CRUNCH */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -